2

標準のカウボーイ 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.

私の懸念はこれです。

[{_,Cnt}]=ets:lookup(req_stats,req_count)が戻る前に数回更新される可能性があるため、高負荷の下で各 Web リクエストに対して count_req() を呼び出すと、不正確なカウントになる可能性が高くなります。カウント+1

ets は、インクリメント操作のように、更新と読み取りを一度に行う手段を提供しますか?

ありがとう。

4

1 に答える 1

8

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}]
于 2014-01-08T18:14:50.320 に答える