erlang - ets 是否提供了一种一次性进行更新和读取的方法——比如增量操作?

标签 erlang increment ets

在设置我的标准 Cowboy Web 处理例程之前,我在我的 start(_StartType, _StartArgs) -> 函数中初始化了一个命名的 ets 表。

ets:new(req_stats,[named_table,public]),ets:insert(req_stats,{req_count,0})

我有这个功能:

 count_req()->
    [{_,Cnt}]=ets:lookup(req_stats,req_count),
    ets:insert(req_stats,Cnt+1),
    Cnt+1.

我担心的是这个;

如果我在高负载下为每个 Web 请求调用 count_req(),我很可能会得到一个不准确的计数,因为 [{_,Cnt}]=ets:lookup(req_stats,req_count) 在我返回 Cnt+1 之前可以更新几次

ets 是否提供了一种一次性更新和读取的方法——比如增量操作?

谢谢。

最佳答案

您可以使用 ets:update_counter/3 :

ets:update_counter(req_stats, req_count, {2, 1})

也就是说,将元组的第 2 个元素加 1,并返回新值。


在 Erlang/OTP 18.0(2015-06-24 发布)中,引入了 ets:update_counter/4。它允许您提供一个默认值,以便在表中不存在该键时使用。因此,如果您希望计数器在第一次递增后变为 1,请将 0 作为默认值:

1> ets:new(req_stats, [named_table]).
req_stats
2> ets:tab2list(req_stats).
[]
3> ets:update_counter(req_stats, req_count, {2, 1}, {req_count, 0}).
1
4> ets:tab2list(req_stats).
[{req_count,1}]

关于erlang - ets 是否提供了一种一次性进行更新和读取的方法——比如增量操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21003292/

相关文章:

erlang - 将元组转换为 proplists

list - 在 Erlang 中创建列表列表

arrays - Erlang中的大型可变字节数组

JavaScript/设置从 0 开始递增索引

concurrency - Erlang 中的 PID 列表

php - MYSQL INNODB 手动加锁自增

objective-c - 在NSArray中增加NSNumber

erlang - 如何更新 ets 表中存储的元组内的数字?

concurrency - Erlang ETS 插入/2 错误

concurrency - 在 Erlang 中将消息路由到 PID