查看源代码 counters (erts v15.2)

计数器函数

此模块提供了一组函数,用于对共享的可变计数器变量进行操作。该实现不使用任何软件级别的锁定,这使得它在并发访问时非常高效。计数器被组织成具有以下语义的数组:

  • 计数器是 64 位有符号整数。
  • 计数器在溢出和下溢操作时会回绕。
  • 计数器初始化为零。
  • 写入操作保证原子性。从单个写入操作中看不到任何中间结果。
  • 可以使用选项 atomicswrite_concurrency 创建两种类型的计数器数组。atomics 计数器具有良好的整体性能和一致的语义,而 write_concurrency 计数器则以潜在的读取不一致为代价,提供更好的并发写入性能。请参见 new/2
  • 计数器数组的索引是从 1 开始的。大小为 N 的计数器数组包含 N 个计数器,索引从 1 到 N。

概要

类型

标识从 new/2 返回的计数器数组。

函数

Incr 加到索引为 Ix 的计数器上。

读取计数器值。

以映射的形式返回有关计数器数组的信息。

创建一个新的包含 Size 个计数器的计数器数组。数组中的所有计数器最初都设置为零。

Value 写入索引为 Ix 的计数器。

从索引为 Ix 的计数器中减去 Decr

类型

链接到此不透明类型

counters_ref()

查看源代码 (自 OTP 21.2 起)
-opaque counters_ref()

标识从 new/2 返回的计数器数组。

函数

链接到此函数

add(Ref, Ix, Incr)

查看源代码 (自 OTP 21.2 起)
-spec add(Ref, Ix, Incr) -> ok when Ref :: counters_ref(), Ix :: integer(), Incr :: integer().

Incr 加到索引为 Ix 的计数器上。

链接到此函数

get(Ref, Ix)

查看源代码 (自 OTP 21.2 起)
-spec get(Ref, Ix) -> integer() when Ref :: counters_ref(), Ix :: integer().

读取计数器值。

链接到此函数

info(Ref)

查看源代码 (自 OTP 21.2 起)
-spec info(Ref) -> Info
              when
                  Ref :: counters_ref(),
                  Info :: #{size := Size, memory := Memory},
                  Size :: non_neg_integer(),
                  Memory :: non_neg_integer().

以映射的形式返回有关计数器数组的信息。

该映射具有以下键(至少):

  • size - 数组中计数器的数量。
  • memory - 数组的近似内存消耗(以字节为单位)。
链接到此函数

new(Size, Opts)

查看源代码 (自 OTP 21.2 起)
-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 - 这是一种优化,可以以每个计数器的潜在读取不一致和内存消耗为代价,实现非常高效的并发 addsub 操作。

    读取操作可能会看到与并发写入操作相关的顺序不一致的结果。即使写入操作 A 在写入操作 B 之前按顺序完成,并发读取器也可能会看到 A 和 B 的任何组合,包括仅看到 B。读取操作仅保证看到在读取之前按顺序完成的所有写入。永远不会丢失任何写入,但最终都会被看到。

    write_concurrency 的典型用例是,当对同一计数器的 addsub 的并发调用非常频繁时,而对 getput 的调用则不那么频繁。也必须可以接受缺乏绝对的读取一致性。

计数器不与当前进程绑定,并且在不再被引用时会自动进行垃圾回收。

链接到此函数

put(Ref, Ix, Value)

查看源代码 (自 OTP 21.2 起)
-spec put(Ref, Ix, Value) -> ok when Ref :: counters_ref(), Ix :: integer(), Value :: integer().

Value 写入索引为 Ix 的计数器。

注意

尽管名称如此,write_concurrency 优化并不会改进 put。与非常轻量级和可扩展的 addsub 相比,调用 put 是一项相对繁重的操作。write_concurrencyput 的成本类似于没有 write_concurrencyget 加上 put

链接到此函数

sub(Ref, Ix, Decr)

查看源代码 (自 OTP 21.2 起)
-spec sub(Ref, Ix, Decr) -> ok when Ref :: counters_ref(), Ix :: integer(), Decr :: integer().

从索引为 Ix 的计数器中减去 Decr