是否提供了更新和更新的方法。一次读入 - 就像增量操作一样?

时间:2014-01-08 18:07:54

标签: erlang increment ets

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

ETS:新的(的 req_stats 下,[named_table,公共]),ETS:插入(req_stats,{的 req_count 下,0})

我有这个功能:

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

我关心的是这个;

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

ets是否提供了进行更新的方法&一次读取 - 就像增量操作一样?

感谢。

1 个答案:

答案 0 :(得分:8)

您可以使用ets:update_counter/3

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

也就是说,将元组的第二个元素递增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}]