在设置标准的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是否提供了进行更新的方法&一次读取 - 就像增量操作一样?
感谢。
答案 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}]