檢視原始碼 counters (erts v15.2)
計數器函數
此模組提供一組函數,用於對共享的可變計數器變數執行操作。 該實作不使用任何軟體層級鎖定,這使其在並行存取時非常有效率。 計數器組織成具有以下語義的陣列:
- 計數器為 64 位元帶符號整數。
- 計數器在溢位和下溢操作時會環繞。
- 計數器初始化為零。
- 寫入操作保證原子性。 單次寫入操作不會出現中間結果。
- 可以使用
atomics
或write_concurrency
選項建立兩種計數器陣列。atomics
計數器具有良好的全方位效能和一致的語義,而write_concurrency
計數器提供更好的並行寫入效能,但會犧牲一些潛在的讀取不一致性。 請參閱new/2
。 - 計數器陣列的索引從 1 開始。大小為 N 的計數器陣列包含 N 個計數器,索引從 1 到 N。
摘要
函數
將 Incr
加到索引 Ix
處的計數器。
讀取計數器值。
在映射中傳回關於計數器陣列的資訊。
建立一個新的計數器陣列,其中包含 Size
個計數器。 陣列中的所有計數器最初都設定為零。
將 Value
寫入到索引 Ix
處的計數器。
從索引 Ix
處的計數器減去 Decr
。
類型
函數
-spec add(Ref, Ix, Incr) -> ok when Ref :: counters_ref(), Ix :: integer(), Incr :: integer().
將 Incr
加到索引 Ix
處的計數器。
-spec get(Ref, Ix) -> integer() when Ref :: counters_ref(), Ix :: integer().
讀取計數器值。
-spec info(Ref) -> Info when Ref :: counters_ref(), Info :: #{size := Size, memory := Memory}, Size :: non_neg_integer(), Memory :: non_neg_integer().
在映射中傳回關於計數器陣列的資訊。
該映射至少具有以下鍵:
size
- 陣列中計數器的數量。memory
- 陣列的近似記憶體消耗量 (以位元組為單位)。
-spec new(Size, Opts) -> counters_ref() when Size :: pos_integer(), Opts :: [Opt], Opt :: atomics | write_concurrency.
建立一個新的計數器陣列,其中包含 Size
個計數器。 陣列中的所有計數器最初都設定為零。
引數 Opts
是下列可能選項的清單:
atomics
(預設值) - 計數器將會是循序一致的。 如果寫入操作 A 在寫入操作 B 之前按順序完成,則並行讀取器可能看不到它們中的任何一個、僅看到 A 或同時看到 A 和 B 的結果。 它無法僅看到 B 的結果。write_concurrency
- 這是一種最佳化,可以在犧牲每個計數器的潛在讀取不一致性和記憶體消耗的情況下,實現非常高效的並行add
和sub
操作。讀取操作可能會看到關於並行寫入操作的循序不一致結果。 即使寫入操作 A 在寫入操作 B 之前按順序完成,並行讀取器也可能看到 A 和 B 的任何組合,包括僅看到 B。 只有在讀取之前按順序完成的所有寫入,才能保證讀取操作看到。 永遠不會遺失任何寫入,但最終都會被看到。
write_concurrency
的典型使用案例是當對相同計數器的add
和sub
的並行呼叫非常頻繁時,而對get
和put
的呼叫則不那麼頻繁。 也必須接受絕對讀取一致性的缺乏。
計數器不會與目前的程序繫結,並且在不再被參考時會自動進行垃圾收集。
-spec put(Ref, Ix, Value) -> ok when Ref :: counters_ref(), Ix :: integer(), Value :: integer().
將 Value
寫入到索引 Ix
處的計數器。
注意
儘管名稱如此,
write_concurrency
最佳化並不會改善put
。 相較於非常輕量且可擴充的add
和sub
,對put
的呼叫相對來說是比較重的操作。 具有write_concurrency
的put
的成本就像是get
加上沒有write_concurrency
的put
。
-spec sub(Ref, Ix, Decr) -> ok when Ref :: counters_ref(), Ix :: integer(), Decr :: integer().
從索引 Ix
處的計數器減去 Decr
。