查看源码 erlang (erts v15.2)
Erlang BIF 和预定义类型。
按照惯例,大多数 内建函数 (BIF) 和所有预定义类型都包含在这个模块中。一些 BIF 和所有的预定义类型都被或多或少地视为 Erlang 编程语言的一部分,并且是自动导入的。因此,不需要指定模块名称。例如,调用 atom_to_list(erlang)
和 erlang:atom_to_list(erlang)
是相同的。
自动导入的 BIF 会用 auto-imported
注释,而预定义类型会用 predefined
注释。
一些自动导入的 BIF 也允许在 守卫表达式 中使用。这样的 BIF 会同时用 auto-imported
和 guard-bif
注释。
BIF 可能因各种原因而失败。如果 BIF 使用了错误类型的参数调用,则所有 BIF 都会因 badarg
失败。其他原因在每个单独的 BIF 的描述中说明。
摘要
预定义数据类型
函数或类型的参数个数。
Erlang 位串。
由整数表示的字节数据。
Erlang fun。
一个包含字节和/或 iodata 的二进制数据或列表。
一个包含字节和/或 iodata 的列表。
一个包含 ContentType
类型项的 Erlang 列表。
表示 模块:函数/参数个数
函数签名的三元组。
由原子表示的 Erlang 模块。
负整数。
用于表示一个函数永远不会返回值,即它将总是抛出异常的类型。
非负整数,即任何正整数或 0。
此类型用于表示函数将永远不返回值;也就是说它将总是抛出异常。
包含一些数据的 binary/0
。
包含一些数据的 bitstring/0
。
包含一些条目的 list/0
。
包含一些字符的 string/0
。
大于零的整数。
Erlang 引用。
由 ASCII 字符或 Unicode 码位列表表示的字符串。
类型
当前的 CPU 拓扑。
time_unit/0
类型也由以下已弃用的符号时间单位组成
标识分发通道的不透明句柄。
一个二进制数据对象,根据 Erlang 外部项格式进行结构化。
类型为 iovec/0
的项,根据 Erlang 外部项格式进行结构化。
包含系统范围垃圾回收默认值的列表。
二进制数据列表。此数据类型可用于 enif_inspect_iovec
。
进程最大堆大小配置。有关更多信息,请参阅 process_flag(max_heap_size, MaxHeapSize)
标识 NIF 资源对象 的不透明句柄。
进程优先级。有关更多信息,请参阅 process_flag(priority, Level)
可以传递给 raise/3
的扩展 stacktrace/0
。
请求的调度器绑定类型。
发送操作的目标。
Erlang 堆栈跟踪,如 Erlang 参考手册中错误和错误处理部分所述。
erlang 时间 API 使用的时间单位。
校验和
计算并返回 Data
的 adler32 校验和。
通过将先前的校验和 OldAdler
与 Data
的校验和组合,继续计算 adler32 校验和。
组合两个先前计算的 adler32 校验和。
计算并返回 Data
的 crc32 (IEEE 802.3 样式) 校验和。
通过将先前的校验和 OldCrc
与 Data
的校验和组合,继续计算 crc32 校验和。
组合两个先前计算的 crc32 校验和。
从 Data
计算 MD5 消息摘要,其中摘要的长度为 128 位(16 字节)。Data
是二进制数据或小的整数和二进制数据的列表。
完成 MD5 Context
的更新并返回计算出的 MD5
消息摘要。
创建 MD5 上下文,用于后续调用 md5_update/2
。
使用 Data
更新 MD5 Context
并返回 NewContext
。
代码
如果 Module
有旧代码,则返回 true
,否则返回 false
。
检查由 Pid
标识的节点本地进程是否为 Module
执行旧代码。
使 Module
的当前代码变为旧代码,并从导出表中删除对此模块的所有引用。如果模块不存在,则返回 undefined
,否则返回 true
。
如果模块 Module
是当前的,并且包含导出的函数 Function/Arity
,或者如果存在具有指定名称的 BIF(在 C 中实现的内建函数),则返回 true
,否则返回 false
。
此 BIF 对于跨引用工具的构建者很有用。
加载 Binary
中包含的目标代码所描述的 Module
。
加载并链接包含模块的本地实现函数 (NIF) 的动态库。
返回所有已加载的 Erlang 模块(当前代码和旧代码),包括预加载的模块的列表。
如果模块 Module
作为当前代码加载,则返回 true
;否则,返回 false
。它不会尝试加载该模块。
返回在运行时系统中预加载的 Erlang 模块列表。
删除 Module
的旧代码。在使用此 BIF 之前,必须调用 check_process_code/2
以检查是否有进程在模块中执行旧代码。
分布式 Erlang
强制断开节点的连接。
从本地节点获取要传递到远程节点的分布式通道数据。
当有更多数据可使用 erlang:dist_ctrl_get_data(DHandle)
获取由 DHandle
标识的分布式通道时,请求通知。
返回由 DHandle
标识的分布式通道上 get_size
选项的值。有关更多信息,请参阅 erlang:dist_ctrl_set_opt/3
函数的 get_size
选项的文档。
为 DHandle
标识的分布式通道注册备用输入处理程序进程。
将来自远程节点的分布式通道数据传递到本地节点。
设置由 DHandle
标识的分布式通道上的 get_size
选项的值。
如果本地节点处于活动状态,则返回本地节点的 magic cookie,否则返回原子 nocookie
。此值由 set_cookie/1
设置。
如果本地节点处于活动状态,则返回节点 Node
的 magic cookie,否则返回原子 nocookie
。此值由 set_cookie/2
设置。
如果本地节点处于活动状态(即,如果该节点可以成为分布式系统的一部分),则返回 true
,否则返回 false
。如果节点以以下方式启动,则该节点处于活动状态
监视节点 Node
的状态。如果 Flag
为 true
,则启用监视。如果 Flag
为 false
,则关闭监视。
行为与 monitor_node/2
相同,但允许指定一个额外的选项,即 allow_passive_connect
。
返回本地节点的名称。如果节点未处于活动状态,则返回 nonode@nohost
。
返回通过正常连接(即,隐藏节点未列出)连接到此节点的所有节点的列表。与 nodes(visible) 相同。
根据指定的参数返回节点列表。当参数为列表时,返回的结果是满足列表元素析取的节点列表。
返回 NodeInfo
元组的列表。
将本地节点的 magic cookie 设置为原子 Cookie
,这也是所有没有使用 set_cookie/2
显式设置 cookie 的节点的 cookie Cookie
。
将 Node
的 magic cookie 设置为原子 Cookie
。如果 Node
是本地节点,则该函数会将所有其他节点(没有使用此函数显式设置 cookie 的节点)的 cookie 设置为 Cookie
。
Erlang 术语
返回一个整数或浮点数,它是 Float
或 Int
的算术绝对值。
返回一个新元组,它比 Tuple1
多一个元素,并包含 Tuple1
中的元素,后跟 Term
作为最后一个元素。
返回与 Atom
的文本表示形式相对应的二进制数据。
返回与 Atom
的文本表示形式相对应的 Unicode 代码点列表。
提取由 PosLen
描述的二进制部分。
返回文本表示形式为 Binary
的原子。如果 Encoding
为 utf8
或 unicode
,则二进制数据必须包含有效的 UTF-8 序列。
与 binary_to_atom/2
相同,但原子必须存在。
返回文本表示形式为 Binary
的浮点数。
返回文本表示形式为 Binary
的整数。
返回以 Base
为基数的文本表示形式为 Binary
的整数。
返回与 Binary
的字节相对应的整数列表。
与 binary_to_list/1
相同,但返回一个整数列表,该列表对应于 Binary
中从位置 Start
到位置 Stop
的字节。二进制数据中的位置从 1 开始编号。
返回 Erlang 术语,它是解码二进制对象 Binary
的结果,该对象必须按照 Erlang 外部术语格式进行编码。
等效于 binary_to_term(Binary)
,但可以配置为适合特殊用途。
返回一个整数,该整数是 Bitstring
的位大小。
返回与 Bitstring
的字节相对应的整数列表。
返回一个整数,该整数是包含 Bitstring
所需的字节数。也就是说,如果 Bitstring
中的位数不能被 8 整除,则结果字节数将向上取整。
返回不小于 Number
的最小整数。
根据 Type
指定的数据包协议解码二进制数据 Bin
。类似于带有选项 {packet,Type}
的套接字所做的数据包处理。
返回一个新元组,该元组的 Index
处的元素已从元组 Tuple1
中删除。
在标准输出上打印 Term
的文本表示形式。
返回 Tuple
的第 N
个元素(从 1 开始编号)。
在不进行编码的情况下,计算以 Erlang 外部术语格式编码的术语的最大字节大小。
在不进行编码的情况下,计算以 Erlang 外部术语格式编码的术语的最大字节大小。
通过将 Number
转换为浮点数来返回浮点数。
返回与 Float
的文本表示形式相对应的二进制数据,使用固定小数点格式。
返回与 Float
的文本表示形式相对应的字符串,使用固定小数点格式。
返回不大于 Number
的最大整数。
返回包含有关函数 Fun
的信息的列表。每个列表元素都是一个元组。元组的顺序未定义,并且可以在将来的版本中添加更多元组。
以 {Item,Info}
的形式返回 Fun
的由 Item
指定的信息。
返回表示创建 Fun
的代码的 String
。
返回 List
的头部,即第一个元素。
返回一个新元组,其中元素 Term
插入到元组 Tuple1
中的位置 Index
。从位置 Index
开始的所有元素都将在新元组 Tuple2
中向上移动一步。
返回与 Integer
的文本表示形式相对应的二进制数据。
返回与以 Base
为基数的 Integer
的文本表示形式相对应的二进制数据。
返回与 Integer
的文本表示形式相对应的字符串。
返回与以 Base
为基数的 Integer
的文本表示形式相对应的字符串。
返回一个整数,该整数是 iolist_to_binary(Item)
的结果二进制数据的大小(以字节为单位)。
返回一个由 IoListOrBinary
中的整数和二进制数据组成的二进制数据。
返回一个由 IoListOrBinary
中的整数和二进制数据组成的 iovec。当你想要展平一个 iolist,但不需要单个二进制数据时,此函数非常有用。这对于将数据传递给 NIF 函数(例如 enif_inspect_iovec
)或进行更高效的消息传递非常有用。与 iolist_to_binary/1
相比,使用此函数的优点是它不必复制 堆外二进制数据。
如果 Term
是原子,则返回 true
,否则返回 false
。
如果 Term
是二进制数据,则返回 true
,否则返回 false
。
如果 Term
是位串(包括二进制数据),则返回 true
,否则返回 false
。
如果 Term
是原子 true
或原子 false
(即布尔值),则返回 true
。否则返回 false
。
如果 Term
是浮点数,则返回 true
,否则返回 false
。
如果 Term
是一个 fun,则返回 true
,否则返回 false
。
如果 Term
是一个可以使用 Arity
个参数应用的 fun,则返回 true
,否则返回 false
。
如果 Term
是整数,则返回 true
,否则返回 false
。
如果 Term
是包含零个或多个元素的列表,则返回 true
,否则返回 false
。
如果 Term
是一个映射,则返回 true
,否则返回 false
。
如果映射 Map
包含 Key
,则返回 true
,如果它不包含 Key
,则返回 false
。
如果 Term
是整数或浮点数,则返回 true
。否则返回 false
。
如果 Term
是进程标识符,则返回 true
,否则返回 false
。
如果 Term
是端口标识符,则返回 true
,否则返回 false
。
如果 Term
是一个元组,且它的第一个元素是 RecordTag
,则返回 true
。否则返回 false
。
RecordTag
必须是原子。
如果 Term
是引用,则返回 true
,否则返回 false
。
如果 Term
是元组,则返回 true
,否则返回 false
。
返回 List
的长度。
返回文本表示形式为 String
的原子。
返回一个由 IoList
中的整数和二进制数据组成的二进制数据。
返回一个由 BitstringList
中的整数和位串组成的位串。(BitstringList
中的最后一个尾部允许是位串。)
返回文本表示形式为 String
的原子,但前提是该原子已存在。如果原子是通过运行时系统加载代码或创建包含该原子的项而创建的,则该原子存在。
返回文本表示形式为 String
的浮点数。
返回文本表示形式为 String
的整数。
返回以 Base
为基数的文本表示形式为 String
的整数。
返回文本表示形式为 String
的进程标识符。
返回文本表示形式为 String
的端口标识符。
返回文本表示形式为 String
的引用。
返回与 List
对应的元组,例如
返回一个唯一引用。该引用在连接的节点之间是唯一的。
创建一个指定 Arity
的新元组,其中所有元素均为 InitialValue
。
创建一个大小为 Arity
的元组,其中每个元素的值为 DefaultValue
,然后从 InitList
中填充值。
如果 Map
包含 Key
,则返回与 Key
关联的值 Value
。
返回一个整数,它是 Map
中键值对的数量。
测试在调用 ets:select/2
和 trace:function/4
中使用的匹配规范。
返回 Term1
和 Term2
中较大的一个。如果使用 ==
运算符比较时,两个项相等,则返回 Term1
。
返回 Term1
和 Term2
中较小的一个。如果使用 ==
运算符比较时,两个项相等,则返回 Term1
。
返回 Arg
的来源节点。Arg
可以是进程标识符、引用或端口。如果 Arg
来自本地节点,并且本地节点未处于活动状态,则返回 nonode@nohost
。
等效于 phash2/2
。
可移植的哈希函数,它为相同的 Erlang 项提供相同的哈希值,而与机器架构和 ERTS 版本无关。
返回与 Pid
的文本表示形式对应的字符串。
返回与端口标识符 Port
的文本表示形式对应的字符串。
返回与 Ref
的文本表示形式对应的字符串。
通过舍入 Number
返回一个整数。
返回一个元组,它是参数 Tuple1
的副本,其中由整数参数 Index
指定的元素(第一个元素的索引为 1)被参数 Value
替换。
返回元组中的元素数量或二进制数据或位串中的字节数。
返回一个元组,其中包含将 Bin
在位置 Pos
处拆分为两部分的结果二进制数据。
返回一个二进制数据对象,它是根据 Erlang 外部项格式 对 Term
进行编码的结果。
返回一个二进制数据对象,它是根据 Erlang 外部项格式对 Term
进行编码的结果。
返回根据 Erlang 外部项格式编码的 Term
,作为 ext_iovec/0
。
返回根据 Erlang 外部项格式编码的 Term
,作为 ext_iovec/0
。
返回 List
的尾部,即列表减去第一个元素
截断 Number
的小数部分。
返回一个整数,它是 Tuple
中的元素数量。
返回与 Tuple
对应的列表。Tuple
可以包含任何 Erlang 项。例如
生成并返回一个在当前运行时系统实例上唯一的整数。等效于调用 erlang:unique_integer([])
。
生成并返回一个在当前运行时系统实例上唯一的整数。该整数是唯一的,因为这个 BIF 使用相同的修饰符集,在当前运行时系统实例上不会多次返回相同的整数。当然,每个整数值都可以通过其他方式构造。
进程和端口
创建一个别名,该别名可在向创建该别名的进程发送消息时使用。当别名被禁用时,使用该别名发送的消息将被丢弃。可以使用 unalias/1
禁用别名。
调用一个 fun,将 Args
中的元素作为参数传递。
返回将 Module
中的 Function
应用于 Args
的结果。应用的函数必须从 Module
导出。函数的arity 是 Args
的长度。
这个依赖于实现的函数会增加调用进程的规约计数器。
如果 MonitorRef
是调用进程通过调用 monitor/2
获取的引用,则此监视将关闭。如果监视已关闭,则不会发生任何操作。
除非 info
是 OptionList
的一部分,否则返回的值为 true
。
返回进程字典并将其删除。
返回与 Key
关联的值 Val
,并将其从进程字典中删除。如果 Key
没有关联的值,则返回 undefined
。
引发一个带有原因 Reason
的 error
类异常。
引发一个带有原因 Reason
的 error
类异常。Args
应该为当前函数的参数列表或原子 none
。
引发一个带有原因 Reason
的 error
类异常。Args
应该为当前函数的参数列表或原子 none
。
引发一个带有退出原因 Reason
的 exit
类异常。
将带有退出原因 Reason
的退出信号发送到由 Pid
标识的进程或端口。
强制立即对正在执行的进程进行垃圾回收。
垃圾回收由 Pid
标识的节点本地进程。
将进程字典作为 {Key, Val}
元组的列表返回。返回列表中的项可以按任意顺序排列。
返回进程字典中与 Key
关联的值 Val
,如果 Key
不存在,则返回 undefined
。
返回进程字典中所有键的列表。返回列表中的项可以是任意顺序。
返回进程字典中与值 Val
关联的键的列表。返回列表中的项可以是任意顺序。
返回正在评估该函数的进程的组长的进程标识符。
将 Pid
的组长设置为 GroupLeader
。通常,当从某个 shell 启动的进程要拥有与 init
不同的组长时会使用此方法。
使调用进程进入等待状态,其内存分配已尽可能减少。如果进程不希望很快收到任何消息,则此方法很有用。
Pid
必须引用本地节点上的进程。
在调用进程和另一个由 PidOrPort
标识的进程或端口之间建立并激活链接。
向由 Item
标识的实体发送类型为 Type
的监视请求。
其工作方式与 error/1
完全相同,但 Dialyzer 认为此 BIF 将返回任意项。当在 NIF 的存根函数中使用,以便在未加载 NIF 库时生成异常时,Dialyzer 不会生成错误警告。
其工作方式与 error/2
完全相同,但 Dialyzer 认为此 BIF 将返回任意项。当在 NIF 的存根函数中使用,以便在未加载 NIF 库时生成异常时,Dialyzer 不会生成错误警告。
返回一个端口标识符,作为打开新 Erlang 端口的结果。端口可以被视为外部 Erlang 进程。
对端口执行同步调用。Operation
和 Data
的含义取决于端口,即端口驱动程序。并非所有端口驱动程序都支持此功能。
关闭一个打开的端口。大致与 Port ! {self(), close}
相同,只是错误行为(见下文),它是同步的,并且端口不回复 {Port, closed}
。
向端口发送数据。与 Port ! {PortOwner, {command, Data}}
相同,只是错误行为并且是同步的(见下文)。
向端口发送数据。port_command(Port, Data, [])
等于 port_command(Port, Data)
。
将端口所有者(连接的端口)设置为 Pid
。大致与 Port ! {Owner, {connect, Pid}}
相同,只是以下几点:
对端口执行同步控制操作。Operation
和 Data
的含义取决于端口,即端口驱动程序。并非所有端口驱动程序都支持此控制功能。
返回包含关于 Port
的信息的元组的列表,如果端口未打开,则返回 undefined
。
返回关于 Port
的信息。
返回与本地节点上存在的所有端口相对应的端口标识符列表。
在 标准错误 上写入关于本地进程 Pid
的信息。
将指示的进程标志设置为指定值。返回标志的先前值。
以与 process_flag/2
相同的方式设置进程 Pid
的某些标志。返回标志的旧值。Flag
的有效值仅是 process_flag/2
中允许的值的子集,即 save_calls
。
返回一个包含关于由 Pid
标识的进程的各种信息的 InfoTuple
列表,如果进程未运行,则返回 undefined
。
返回关于由 Pid
标识的进程的信息,由 Item
或 ItemList
指定。如果进程未运行,则返回 undefined
。
返回与本地节点上当前存在的所有进程相对应的进程标识符列表。
向进程字典添加一个新 Key
,与值 Val
关联,并返回 undefined
。如果 Key
存在,则删除旧值并将其替换为 Val
,该函数返回旧值。
引发指定类、原因和调用堆栈回溯(stacktrace)的异常。
使用 名称注册表
中的进程标识符 (pid) 或端口标识符注册名称 RegName
。RegName
(必须是原子)可以代替发送运算符 (RegName ! Message
) 和大多数其他将 pid 或端口标识符作为参数的 BIF 中的 pid 或端口标识符。
返回已使用 register/2
注册的名称列表。
减少由 Suspendee
标识的进程的挂起计数。
返回调用进程的进程标识符。
发送消息并返回 Msg
。这与使用 发送运算符 相同:Dest ! Msg
。
要么发送消息并返回 ok
,要么不发送消息但返回其他内容(见下文)。否则与 erlang:send/2
相同。
发送消息而不挂起调用者。
返回通过将 Fun
应用于空列表 []
而启动的新进程的进程标识符。否则,其工作方式与 spawn/3
相同。
返回通过将 Fun
应用于 Node
上的空列表 []
而启动的新进程的进程标识符。如果 Node
不存在,则返回无用的 pid。否则,其工作方式与 spawn/3
相同。
返回通过将 Module:Function
应用于 Args
而启动的新进程的进程标识符。
返回通过将 Module:Function
应用于 Node
上的 Args
而启动的新进程的进程标识符 (pid)。如果 Node
不存在,则返回无用的 pid。否则,其工作方式与 spawn/3
相同。
返回通过将 Fun
应用于空列表 []
而启动的新进程的进程标识符。在调用进程和新进程之间原子地创建链接。否则,其工作方式与 spawn/3
相同。
返回通过将 Fun
应用于 Node
上的空列表 []
而启动的新进程的进程标识符 (pid)。在调用进程和新进程之间原子地创建链接。如果 Node
不存在,则返回无用的 pid,并将原因 noconnection
的退出信号发送到调用进程。否则,其工作方式与 spawn/3
相同。
返回通过将 Module:Function
应用于 Args
而启动的新进程的进程标识符。在调用进程和新进程之间原子地创建链接。否则,其工作方式与 spawn/3
相同。
返回通过将 Module:Function
应用于 Node
上的 Args
而启动的新进程的进程标识符 (pid)。在调用进程和新进程之间原子地创建链接。如果 Node
不存在,则返回无用的 pid,并将原因 noconnection
的退出信号发送到调用进程。否则,其工作方式与 spawn/3
相同。
返回一个新进程的进程标识符,该进程通过将 Fun
应用于空列表 []
启动,以及为新进程创建的监视器的引用。否则,其工作方式与 spawn/3
相同。
返回一个新进程的进程标识符,该进程是通过在节点 Node
上将 Fun
应用于空列表 []
而启动的,以及为新进程创建的监视器引用。否则,其工作方式与 spawn/3
相同。
通过将 Module:Function
应用于 Args
来启动一个新进程。同时会监视该进程。返回进程标识符和监视器的引用。否则,其工作方式与 spawn/3
相同。
通过在节点 Node
上将 Module:Function
应用于 Args
来启动一个新进程。同时会监视该进程。返回进程标识符和监视器的引用。否则,其工作方式与 spawn/3
相同。
返回一个新进程的进程标识符(pid),该进程是通过将 Fun
应用于空列表 []
而启动的。否则,其工作方式与 spawn_opt/4
相同。
返回一个新进程的进程标识符(pid),该进程是通过在 Node
上将 Fun
应用于空列表 []
而启动的。如果 Node
不存在,则返回一个无用的 pid。否则,其工作方式与 spawn_opt/4
相同。
与 spawn/3
的工作方式相同,只是在创建进程时指定了一个额外的选项列表。
返回一个新进程的进程标识符(pid),该进程是通过在 Node
上将 Module:Function
应用于 Args
而启动的。如果 Node
不存在,则返回一个无用的 pid。否则,其工作方式与 spawn_opt/4
相同。
等效于调用 spawn_request(node(),Fun,[])
。也就是说,在本地节点上发起一个没有选项的 spawn 请求。
等效于 spawn_request(node(),Fun,Options)
或 spawn_request(Node,Fun,[])
,具体取决于参数。
异步发送一个 spawn 请求。返回一个请求标识符 ReqId
。
放弃先前发出的 spawn 请求。ReqId
对应于先前由当前进程调用 spawn_request()
返回的请求标识符。也就是说,只有发出请求的进程才能放弃该请求。
暂停由 Suspendee
标识的进程。等效于调用 erlang:suspend_process(Suspendee, [])
。
增加由 Suspendee
标识的进程的暂停计数,如果该进程尚未处于暂停状态,则将其置于暂停状态。在进程恢复之前,暂停的进程不会被调度执行。
引发一个类为 throw
的异常。旨在用于从函数执行非本地返回。
停用调用进程先前创建的别名 Alias
。
删除调用进程与由 Id
标识的另一个进程或端口之间的链接。
尝试让具有相同或更高优先级的其他进程(如果有)有机会在返回之前执行。无法保证在 erlang:yield/0
的调用和返回之间有任何其他进程运行。
System
等效于调用 halt(0, [])
。
等效于调用 halt(HaltType, [])
。
停止运行时系统。
返回一个列表,其中包含有关 Erlang 模拟器动态分配的内存的信息。
返回为类型为 Type
的内存分配的内存大小(以字节为单位)。该参数也可以指定为 memory_type/0
原子的列表,在这种情况下,返回一个相应的 {memory_type(), Size :: integer >= 0}
元组列表。
返回有关当前系统的统计信息。
将系统标志设置为给定的值。
返回有关当前系统的信息。
返回由 erlang:system_monitor/2
设置的当前系统监视设置,格式为 {MonitorPid, Options}
,如果不存在任何设置,则返回 undefined
。
当使用参数 undefined
调用时,将清除所有系统性能监视设置。
设置系统性能监视选项。MonitorPid
是接收系统监视器消息的本地进程标识符(pid)。
返回由 erlang:system_profile/2
设置的当前系统分析设置,格式为 {ProfilerPid, Options}
,如果没有设置,则返回 undefined
。选项的顺序可能与设置的顺序不同。
设置系统分析器选项。ProfilerPid
是接收分析消息的本地进程标识符(pid)或端口。接收者被排除在所有分析之外。第二个参数是一个分析选项列表。
Time and timers
等效于 erlang:cancel_timer(TimerRef, [])
。
取消由 erlang:start_timer
或 erlang:send_after
创建的计时器。TimerRef
标识该计时器,并且由创建该计时器的 BIF 返回。
将时间单位为 FromUnit
的 Time
值转换为时间单位为 ToUnit
的相应 ConvertedTime
值。使用 floor/1
函数对结果进行舍入。
以 {Year, Month, Day}
格式返回当前日期。
返回当前的本地日期和时间,{{Year, Month, Day}, {Hour, Minute, Second}}
。
如果底层操作系统支持,则将本地日期和时间转换为协调世界时 (UTC)。否则,不进行转换,并返回 Localtime
。
与 erlang:localtime_to_universaltime/1
相同,将本地日期和时间转换为协调世界时 (UTC),但调用者决定是否启用夏令时。
以 native
时间单位 返回当前的 Erlang 单调时间。这是自某个未指定的时间点以来单调递增的时间。
返回转换为作为参数传递的 Unit
的当前 Erlang 单调时间。
等效于 erlang:read_timer(TimerRef, [])
。
读取由 erlang:start_timer
或 erlang:send_after
创建的计时器的状态。TimerRef
标识该计时器,并且由创建该计时器的 BIF 返回。
等效于 erlang:send_after(Time, Dest, Msg, [])
。
启动计时器。当计时器到期时,消息 Msg
将发送到由 Dest
标识的进程。除了超时消息的格式之外,此函数的工作方式与 erlang:start_timer/4
完全相同。
等效于 erlang:start_timer(Time, Dest, Msg, [])
。
启动计时器。当计时器到期时,消息 {timeout, TimerRef, Msg}
将发送到由 Dest
标识的进程。
以 native
时间单位 返回当前的 Erlang 系统时间。
返回转换为作为参数传递的 Unit
的当前 Erlang 系统时间。
以 {Hour, Minute, Second}
格式返回当前时间。
以 native
时间单位 返回 Erlang 单调时间 和 Erlang 系统时间 之间的当前时间偏移量。将当前时间偏移量添加到 Erlang 单调时间即可得到相应的 Erlang 系统时间。
返回 Erlang 单调时间 和 Erlang 系统时间 之间当前的时间偏移量,并转换为作为参数传递的 Unit
单位。
以 {MegaSecs, Secs, MicroSecs}
格式返回当前的 Erlang 系统时间。
如果底层操作系统支持,则以 {{Year, Month, Day}, {Hour, Minute, Second}}
形式返回协调世界时 (UTC) 的当前日期和时间。否则,erlang:universaltime()
等同于 erlang:localtime()
。返回值基于 操作系统系统时间。
如果底层操作系统支持,则将协调世界时 (UTC) 日期和时间转换为本地日期和时间,格式为 {{Year, Month, Day}, {Hour, Minute, Second}}
。否则,不进行转换,并返回 Universaltime
。
跟踪
为静态传统跟踪会话打开或关闭进程或端口的跟踪标志。
调用此函数确保所有跟踪消息都已传递。
为静态传统跟踪会话返回有关端口、进程、函数或事件的跟踪信息。
为静态传统跟踪会话设置调用、发送和接收跟踪的跟踪模式。
已弃用的函数
警告
此函数已弃用。请勿使用它。
警告
此函数已弃用,因为新代码应使用
erlang:phash2/2
。请注意,erlang:phash(X,N)
不一定等于erlang:phash2(X,N)
预定义的数据类型
-type nil() :: [].
空的 list/0
。
-type any() :: any().
所有可能的 Erlang 项。是 term/0
的同义词。
-type arity() :: arity().
函数或类型的参数个数。
-type atom() :: atom().
Erlang 原子。
-type binary() :: <<_:_*8>>.
Erlang 二进制数据,也就是大小可以被 8 整除的位串。
-type bitstring() :: <<_:_*1>>.
Erlang 位串。
-type boolean() :: true | false.
布尔值。
-type byte() :: 0..255.
由整数表示的字节数据。
-type char() :: 0..1114111.
由整数表示的 ASCII 字符或 unicode
码位。
-type dynamic() :: dynamic().
动态类型,表示静态未知的类型。
-type float() :: float().
Erlang 浮点数。
-type function() :: fun().
Erlang fun。
-type integer() :: integer().
Erlang 整数。
一个包含字节和/或 iodata 的二进制数据或列表。
此数据类型用于表示要使用任何 I/O 模块输出的数据。例如:file:write/2
或 gen_tcp:send/2
。
要将 iodata/0
项转换为 binary/0
,可以使用 iolist_to_binary/2。要将 string/0
或 unicode:chardata/0
转码为 iodata/0
,可以使用 unicode:characters_to_binary/1
。
-type iolist() :: maybe_improper_list(byte() | binary() | iolist(), binary() | []).
一个包含字节和/或 iodata 的列表。
此数据类型用于表示要使用任何 I/O 模块输出的数据。例如:file:write/2
或 gen_tcp:send/2
。
在大多数用例中,您希望使用 iodata/0
而不是此类型。
-type list() :: [any()].
一个包含任何类型项的 Erlang 列表。
-type list(ContentType) :: [ContentType].
一个包含 ContentType
类型项的 Erlang 列表。
一个包含任意数量键值对的 Erlang 映射。
-type maybe_improper_list() :: maybe_improper_list(any(), any()).
-type maybe_improper_list(ContentType, TerminationType) :: maybe_improper_list(ContentType, TerminationType).
表示 模块:函数/参数个数
函数签名的三元组。
-type module() :: atom().
由原子表示的 Erlang 模块。
-type neg_integer() :: neg_integer().
负整数。
-type no_return() :: none().
用于表示一个函数永远不会返回值,即它将总是抛出异常的类型。
-type node() :: atom().
由原子表示的 Erlang 节点。
-type non_neg_integer() :: non_neg_integer().
非负整数,即任何正整数或 0。
-type none() :: none().
此类型用于表示函数将永远不返回值;也就是说它将总是抛出异常。
在规范中,为了清晰起见,请使用 no_return/0
。
-type nonempty_binary() :: <<_:8, _:_*8>>.
包含一些数据的 binary/0
。
-type nonempty_bitstring() :: <<_:1, _:_*1>>.
包含一些数据的 bitstring/0
。
-type nonempty_improper_list(ContentType, TerminationType) :: nonempty_improper_list(ContentType, TerminationType).
包含一些条目的 maybe_improper_list/2。
-type nonempty_list() :: [any(), ...].
包含一些条目的 list/0
。
-type nonempty_list(ContentType) :: [ContentType, ...].
包含一些条目的 list(ContentType)。
-type nonempty_maybe_improper_list() :: nonempty_maybe_improper_list(any(), any()).
包含一些条目的 maybe_improper_list/0
。
-type nonempty_maybe_improper_list(ContentType, TerminationType) :: nonempty_maybe_improper_list(ContentType, TerminationType).
-type nonempty_string() :: [char(), ...].
包含一些字符的 string/0
。
Erlang 数字。
-type pid() :: pid().
Erlang 进程标识符。
-type port() :: port().
Erlang 端口标识符。
-type pos_integer() :: pos_integer().
大于零的整数。
-type reference() :: reference().
Erlang 引用。
-type string() :: [char()].
由 ASCII 字符或 Unicode 码位列表表示的字符串。
-type term() :: any().
所有可能的 Erlang 项。是 any/0
的同义词。
-type timeout() :: infinity | non_neg_integer().
可以传递给 接收表达式 的超时值。
-type tuple() :: tuple().
Erlang 元组。
类型
-type bitstring_list() :: maybe_improper_list(byte() | bitstring() | bitstring_list(), bitstring() | []).
-type cpu_topology() :: [LevelEntry :: level_entry()] | undefined.
当前的 CPU 拓扑。
node
指的是非一致内存访问(NUMA)节点。thread
指的是硬件线程(例如,Intel 超线程)。
如果只有一个条目且 InfoList
为空,则可以省略术语 CpuTopology
中的级别。
thread
只能是 core
的子级别。core
可以是 processor
或 node
的子级别。processor
可以位于顶层或作为 node
的子级别。node
可以位于顶层或作为 processor
的子级别。也就是说,NUMA 节点可以是处理器内部的或处理器外部的。CPU 拓扑可以由处理器内部和外部的 NUMA 节点混合组成,只要每个逻辑 CPU 属于一个 NUMA 节点。缓存层次结构不是 CpuTopology
类型的一部分,但将在未来版本中加入。其他内容也可能在未来的版本中加入 CPU 拓扑。因此,请预期 CpuTopology
类型会发生变化。
-type deprecated_time_unit() :: seconds | milli_seconds | micro_seconds | nano_seconds.
time_unit/0
类型也由以下已弃用的符号时间单位组成
seconds
- 与second
相同。milli_seconds
- 与millisecond
相同。micro_seconds
- 与microsecond
相同。nano_seconds
- 与nanosecond
相同。
-opaque dist_handle()
标识分发通道的不透明句柄。
-type ext_binary() :: binary().
一个二进制数据对象,根据 Erlang 外部项格式进行结构化。
-type ext_iovec() :: iovec().
类型为 iovec/0
的项,根据 Erlang 外部项格式进行结构化。
-type fun_info_item() :: arity | env | index | name | module | new_index | new_uniq | pid | type | uniq.
-type garbage_collection_defaults() :: [{max_heap_size, non_neg_integer()} | {min_bin_vheap_size, non_neg_integer()} | {min_heap_size, non_neg_integer()} | {fullsweep_after, non_neg_integer()}].
包含系统范围垃圾回收默认值的列表。
-type halt_options() :: [{flush, boolean()} | {flush_timeout, Timeout :: 0..2147483647 | infinity}].
-type info_list() :: [].
-type iovec() :: [binary()].
二进制数据列表。此数据类型可用于 enif_inspect_iovec
。
-type level_tag() :: core | node | processor | thread.
-type match_variable() :: atom().
-type max_heap_size() :: Size :: non_neg_integer() | #{size => non_neg_integer(), kill => boolean(), error_logger => boolean(), include_shared_binaries => boolean()}.
进程最大堆大小配置。有关更多信息,请参阅 process_flag(max_heap_size, MaxHeapSize)
-type memory_type() ::
total | processes | processes_used | system | atom | atom_used | binary | code | ets.
-type message_queue_data() :: off_heap | on_heap.
请参阅 process_flag(message_queue_data, MQD)
。
进程消息队列数据配置。有关更多信息,请参见 process_flag(message_queue_data, MQD)
-type monitor_option() :: {alias, explicit_unalias | demonitor | reply_demonitor} | {tag, term()}.
请参阅 monitor/3
。
-type monitor_port_identifier() :: port() | registered_name().
-type monitor_process_identifier() :: pid() | registered_process_identifier().
-opaque nif_resource()
标识 NIF 资源对象 的不透明句柄。
-opaque prepared_code()
-type priority_level() :: low | normal | high | max.
进程优先级。有关更多信息,请参阅 process_flag(priority, Level)
-type process_info_item() :: async_dist | backtrace | binary | catchlevel | current_function | current_location | current_stacktrace | dictionary | {dictionary, Key :: term()} | error_handler | garbage_collection | garbage_collection_info | group_leader | heap_size | initial_call | links | label | last_calls | memory | message_queue_len | messages | min_heap_size | min_bin_vheap_size | monitored_by | monitors | message_queue_data | parent | priority | reductions | registered_name | sequential_trace_token | stack_size | status | suspending | total_heap_size | trace | trap_exit.
-type process_info_result_item() :: {async_dist, Enabled :: boolean()} | {backtrace, Bin :: binary()} | {binary, BinInfo :: [{non_neg_integer(), non_neg_integer(), non_neg_integer()}]} | {catchlevel, CatchLevel :: non_neg_integer()} | {current_function, {Module :: module(), Function :: atom(), Arity :: arity()} | undefined} | {current_location, {Module :: module(), Function :: atom(), Arity :: arity(), Location :: [{file, Filename :: string()} | {line, Line :: pos_integer()}]}} | {current_stacktrace, Stack :: [stack_item()]} | {dictionary, Dictionary :: [{Key :: term(), Value :: term()}]} | {{dictionary, Key :: term()}, Value :: term()} | {error_handler, Module :: module()} | {garbage_collection, GCInfo :: [{atom(), non_neg_integer()}]} | {garbage_collection_info, GCInfo :: [{atom(), non_neg_integer()}]} | {group_leader, GroupLeader :: pid()} | {heap_size, Size :: non_neg_integer()} | {initial_call, mfa()} | {links, PidsAndPorts :: [pid() | port()]} | {label, term()} | {last_calls, false | (Calls :: [mfa()])} | {memory, Size :: non_neg_integer()} | {message_queue_len, MessageQueueLen :: non_neg_integer()} | {messages, MessageQueue :: [term()]} | {min_heap_size, MinHeapSize :: non_neg_integer()} | {min_bin_vheap_size, MinBinVHeapSize :: non_neg_integer()} | {max_heap_size, MaxHeapSize :: max_heap_size()} | {monitored_by, MonitoredBy :: [pid() | port() | nif_resource()]} | {monitors, Monitors :: [{process | port, Pid :: pid() | port() | {RegName :: atom(), Node :: node()}}]} | {message_queue_data, MQD :: message_queue_data()} | {parent, pid() | undefined} | {priority, Level :: priority_level()} | {reductions, Number :: non_neg_integer()} | {registered_name, [] | (Atom :: atom())} | {sequential_trace_token, [] | (SequentialTraceToken :: term())} | {stack_size, Size :: non_neg_integer()} | {status, Status :: exiting | garbage_collecting | waiting | running | runnable | suspended} | {suspending, SuspendeeList :: [{Suspendee :: pid(), ActiveSuspendCount :: non_neg_integer(), OutstandingSuspendCount :: non_neg_integer()}]} | {total_heap_size, Size :: non_neg_integer()} | {trace, InternalTraceFlags :: non_neg_integer()} | {trap_exit, Boolean :: boolean()}.
-type raise_stacktrace() :: [{module(), atom(), arity() | [term()]} | {function(), arity() | [term()]}] | stacktrace().
可以传递给 raise/3
的扩展 stacktrace/0
。
-type registered_name() :: atom().
-type registered_process_identifier() :: registered_name() | {registered_name(), node()}.
-type scheduler_bind_type() ::
no_node_processor_spread | no_node_thread_spread | no_spread | processor_spread | spread |
thread_spread | thread_no_node_processor_spread | unbound.
请求的调度器绑定类型。
-type send_destination() :: pid() | reference() | port() | (RegName :: atom()) | {RegName :: atom(), Node :: node()}.
发送操作的目标。
这可以是远程或本地进程标识符,(本地)端口,表示进程别名的引用,本地注册的名称,或用于在另一个节点注册的名称的元组 {RegName, Node}
。
-type spawn_opt_option() :: link | monitor | {monitor, MonitorOpts :: [monitor_option()]} | {priority, Level :: priority_level()} | {fullsweep_after, Number :: non_neg_integer()} | {min_heap_size, Size :: non_neg_integer()} | {min_bin_vheap_size, VSize :: non_neg_integer()} | {max_heap_size, Size :: max_heap_size()} | {message_queue_data, MQD :: message_queue_data()} | {async_dist, Enabled :: boolean()}.
spawn_opt()
的选项。
-type stacktrace() :: [{module(), atom(), arity() | [term()], [stacktrace_extrainfo()]} | {function(), arity() | [term()], [stacktrace_extrainfo()]}].
Erlang 堆栈跟踪,如 Erlang 参考手册中错误和错误处理部分所述。
-type stacktrace_extrainfo() :: {line, pos_integer()} | {file, unicode:chardata()} | {error_info, #{module => module(), function => atom(), cause => term()}} | {atom(), term()}.
-type sub_level() :: [LevelEntry :: level_entry()] | (LogicalCpuId :: {logical, non_neg_integer()}).
-type system_monitor_option() :: busy_port | busy_dist_port | {long_gc, non_neg_integer()} | {long_message_queue, {Disable :: non_neg_integer(), Enable :: pos_integer()}} | {long_schedule, non_neg_integer()} | {large_heap, non_neg_integer()}.
-type system_profile_option() ::
exclusive | runnable_ports | runnable_procs | scheduler | timestamp | monotonic_timestamp |
strict_monotonic_timestamp.
-type time_unit() :: pos_integer() | second | millisecond | microsecond | nanosecond | native | perf_counter | deprecated_time_unit().
erlang 时间 API 使用的时间单位。
支持的时间单位表示
PartsPerSecond :: integer() >= 1
- 以每秒的份数表示的时间单位。也就是说,时间单位等于1/PartsPerSecond
秒。second
- 由整数1
表示的时间单位的符号表示。millisecond
- 由整数1000
表示的时间单位的符号表示。microsecond
- 由整数1000_000
表示的时间单位的符号表示。nanosecond
- 由整数1000_000_000
表示的时间单位的符号表示。native
- Erlang 运行时系统使用的本地时间单位的符号表示。native
时间单位在运行时系统启动时确定,并在运行时系统终止之前保持不变。如果一个运行时系统停止然后再次启动(即使在同一台机器上),则新的运行时系统实例的native
时间单位可能与旧的运行时系统实例的native
时间单位不同。可以通过调用
erlang:convert_time_unit(1, second, native)
来获得对native
时间单位的近似值。结果等于每秒的native
时间单位的整数个数。如果每秒的native
时间单位个数不是整数,则向下取整。注意
native
时间单位的值或多或少没有提供关于时间值的质量的信息。它为时间值的分辨率和精度设置了限制,但它没有提供关于时间值的准确性的信息。native
时间单位的分辨率和时间值的分辨率可能存在显著差异。perf_counter
- Erlang 运行时系统使用的性能计数器时间单位的符号表示。perf_counter
时间单位的行为方式与native
时间单位非常相似。也就是说,它在运行时重启之间可能会有所不同。要获取此类型的值,请调用os:perf_counter/0
。deprecated_time_unit/0
- 为向后兼容性保留的已弃用的符号表示。
time_unit/0
类型可以扩展。要在时间单位之间转换时间值,请使用 erlang:convert_time_unit/3
。
-type timestamp() :: {MegaSecs :: non_neg_integer(), Secs :: non_neg_integer(), MicroSecs :: non_neg_integer()}.
请参阅 erlang:timestamp/0
。
-type trace_flag() :: all | send | 'receive' | procs | ports | call | arity | return_to | silent | running | exiting | running_procs | running_ports | garbage_collection | timestamp | cpu_timestamp | monotonic_timestamp | strict_monotonic_timestamp | set_on_spawn | set_on_first_spawn | set_on_link | set_on_first_link | {tracer, pid() | port()} | {tracer, module(), term()}.
-type trace_info_flag() ::
send | 'receive' | set_on_spawn | call | return_to | procs | set_on_first_spawn |
set_on_link | running | garbage_collection | timestamp | monotonic_timestamp |
strict_monotonic_timestamp | arity.
-type trace_info_item_result() :: {traced, global | local | false | undefined} | {match_spec, trace_match_spec() | false | undefined} | {meta, pid() | port() | false | undefined | []} | {meta, module(), term()} | {meta_match_spec, trace_match_spec() | false | undefined} | {call_count, non_neg_integer() | boolean() | undefined} | {call_time | call_memory, [{pid(), non_neg_integer(), non_neg_integer(), non_neg_integer()}] | boolean() | undefined}.
-type trace_info_return() :: undefined | {flags, [trace_info_flag()]} | {tracer, pid() | port() | []} | {tracer, module(), term()} | trace_info_item_result() | {all, [trace_info_item_result()] | false | undefined}.
-type trace_match_spec() :: [{[term()] | '_' | match_variable(), [term()], [term()]}].
校验和
-spec adler32(Data) -> non_neg_integer() when Data :: iodata().
计算并返回 Data
的 adler32 校验和。
-spec adler32(OldAdler, Data) -> non_neg_integer() when OldAdler :: non_neg_integer(), Data :: iodata().
通过将先前的校验和 OldAdler
与 Data
的校验和组合,继续计算 adler32 校验和。
以下代码
X = erlang:adler32(Data1),
Y = erlang:adler32(X,Data2).
将与此相同的值赋值给 Y
Y = erlang:adler32([Data1,Data2]).
-spec adler32_combine(FirstAdler, SecondAdler, SecondSize) -> non_neg_integer() when FirstAdler :: non_neg_integer(), SecondAdler :: non_neg_integer(), SecondSize :: non_neg_integer().
组合两个先前计算的 adler32 校验和。
此计算需要知道第二个校验和的数据对象的大小。
以下代码
Y = erlang:adler32(Data1),
Z = erlang:adler32(Y,Data2).
将与此相同的值赋值给 Z
X = erlang:adler32(Data1),
Y = erlang:adler32(Data2),
Z = erlang:adler32_combine(X,Y,iolist_size(Data2)).
-spec crc32(Data) -> non_neg_integer() when Data :: iodata().
计算并返回 Data
的 crc32 (IEEE 802.3 样式) 校验和。
-spec crc32(OldCrc, Data) -> non_neg_integer() when OldCrc :: non_neg_integer(), Data :: iodata().
通过将先前的校验和 OldCrc
与 Data
的校验和组合,继续计算 crc32 校验和。
以下代码
X = erlang:crc32(Data1),
Y = erlang:crc32(X,Data2).
将与此相同的值赋值给 Y
Y = erlang:crc32([Data1,Data2]).
-spec crc32_combine(FirstCrc, SecondCrc, SecondSize) -> non_neg_integer() when FirstCrc :: non_neg_integer(), SecondCrc :: non_neg_integer(), SecondSize :: non_neg_integer().
组合两个先前计算的 crc32 校验和。
此计算需要知道第二个校验和的数据对象的大小。
以下代码
Y = erlang:crc32(Data1),
Z = erlang:crc32(Y,Data2).
将与此相同的值赋值给 Z
X = erlang:crc32(Data1),
Y = erlang:crc32(Data2),
Z = erlang:crc32_combine(X,Y,iolist_size(Data2)).
从 Data
计算 MD5 消息摘要,其中摘要的长度为 128 位(16 字节)。Data
是二进制数据或小的整数和二进制数据的列表。
有关 MD5 的更多信息,请参见 RFC 1321 - MD5 消息摘要算法。
警告
MD5 消息摘要算法不被认为是代码签名或软件完整性目的的安全算法。
完成 MD5 Context
的更新并返回计算出的 MD5
消息摘要。
-spec md5_init() -> Context when Context :: binary().
创建 MD5 上下文,用于后续调用 md5_update/2
。
-spec md5_update(Context, Data) -> NewContext when Context :: binary(), Data :: iodata(), NewContext :: binary().
使用 Data
更新 MD5 Context
并返回 NewContext
。
代码
如果 Module
有旧代码,则返回 true
,否则返回 false
。
另请参见 code
。
-spec check_process_code(Pid, Module, OptionList) -> CheckResult | async when Pid :: pid(), Module :: module(), RequestId :: term(), Option :: {async, RequestId} | {allow_gc, boolean()}, OptionList :: [Option], CheckResult :: boolean() | aborted.
检查由 Pid
标识的节点本地进程是否为 Module
执行旧代码。
Option
s
{allow_gc, boolean()}
- 确定在执行操作时是否允许垃圾回收。如果传递{allow_gc, false}
,并且需要垃圾回收来确定操作的结果,则操作将被中止(请参阅下面的CheckResult
的信息)。默认值为允许垃圾回收,即{allow_gc, true}
。{async, RequestId}
- 函数check_process_code/3
在请求发送后立即返回值async
。当请求被处理后,调用此函数的进程会收到一条形式为{check_process_code, RequestId, CheckResult}
的消息。
如果 Pid
等于 self/0
,并且没有传递 async
选项,则操作会立即执行。否则,将向 Pid
标识的进程发送操作请求,并在适当的时候进行处理。如果没有传递 async
选项,则调用者将阻塞,直到 CheckResult
可用并可以返回。
CheckResult
告知请求的结果如下
true
-Pid
标识的进程为Module
执行旧代码。也就是说,进程的当前调用为该模块执行旧代码,或者进程具有对该模块的旧代码的引用,或者进程包含引用该模块的旧代码的 fun。false
-Pid
标识的进程不为Module
执行旧代码。aborted
- 操作被中止,因为进程需要进行垃圾回收才能确定操作结果,并且该操作是通过传递选项{allow_gc, false}
请求的。
变更
在 ERTS 8.* 版本之前,检查进程代码操作会检查对旧代码的所有类型的引用。也就是说,直接引用(例如,进程堆栈上的返回地址)、间接引用(进程上下文中的
fun
)以及对代码中文字量的引用。从 ERTS 9.0 版本开始,检查进程代码操作仅检查对代码的直接引用。通过
fun
的间接引用将被忽略。如果存在这样的fun
并且在清除旧代码后使用,则在使用时将引发异常(与在清除后进程接收到fun
的情况相同)。文字将在稍后阶段被处理(复制)。从 ERTS 8.1 版本开始,当构建 OTP时可以启用此行为,如果启用了脏调度器支持,则会自动启用此行为。
另请参见 code
。
失败
badarg
- 如果Pid
不是节点本地进程标识符。badarg
- 如果Module
不是原子。badarg
- 如果OptionList
是无效的选项列表。
-spec delete_module(Module) -> true | undefined when Module :: module().
使 Module
的当前代码变为旧代码,并从导出表中删除对此模块的所有引用。如果模块不存在,则返回 undefined
,否则返回 true
。
警告
此 BIF 用于代码服务器(参见
code
),不应在其他地方使用。
失败:如果 Module
已经存在旧版本,则返回 badarg
。
-spec function_exported(Module, Function, Arity) -> boolean() when Module :: module(), Function :: atom(), Arity :: arity().
如果模块 Module
是当前的,并且包含导出的函数 Function/Arity
,或者如果存在具有指定名称的 BIF(在 C 中实现的内建函数),则返回 true
,否则返回 false
。
-spec is_builtin(Module, Function, Arity) -> boolean() when Module :: module(), Function :: atom(), Arity :: arity().
此 BIF 对于跨引用工具的构建者很有用。
如果 Module:Function/Arity
是用 C 实现的 BIF,则返回 true
,否则返回 false
。
-spec load_module(Module, Binary) -> {module, Module} | {error, Reason} when Module :: module(), Binary :: binary(), Reason :: badfile | not_purged | on_load | {features_not_allowed, [atom()]}.
加载 Binary
中包含的目标代码所描述的 Module
。
如果模块 Module
的代码已存在,则所有导出引用都会被替换,使其指向新加载的代码。先前加载的代码作为旧代码保留在系统中,因为仍然可能有进程在执行该代码。
如果加载失败,则返回 {module, Module}
或 {error, Reason}
。Reason
是以下之一
badfile
-Binary
中的目标代码格式不正确或者目标代码包含的模块代码与Module
不同。not_purged
-Binary
包含一个无法加载的模块,因为该模块的旧代码已存在。on_load
-Binary
中的代码包含一个on_load
声明,必须先执行该声明,Binary
才能成为当前代码。在on_load
调用完成之前,Module
的任何先前的当前代码都将保留。not_allowed -
Binary
中的代码使用了一些当前在运行时系统中未启用的功能进行了编译。
警告
此 BIF 用于代码服务器(参见
code
),不应在其他地方使用。
-spec load_nif(Path, LoadInfo) -> ok | Error when Path :: string(), LoadInfo :: term(), Error :: {error, {Reason, Text :: string()}}, Reason :: load_failed | bad_lib | load | reload | upgrade | old_code.
加载并链接包含模块的本地实现函数 (NIF) 的动态库。
Path
是共享对象/动态库文件的文件路径,不包括操作系统相关的文件扩展名(Unix 为 .so
,Windows 为 .dll
)。请注意,在大多数操作系统上,当 NIF 升级时,库在磁盘上的名称必须不同。如果名称相同但内容不同,则可能会加载旧库。有关如何实现 NIF 库的信息,请参阅 erl_nif(3)
。
LoadInfo
可以是任何项。它作为初始化的一部分传递给库。最佳实践是包含模块版本号,以支持将来的代码升级场景。
对 load_nif/2
的调用必须直接从 NIF 库所属模块的 Erlang 代码中进行。如果加载失败,则返回 ok
或 {error,{Reason,Text}}
。Reason
是以下原子之一,而 Text
是人类可读的字符串,可以提供有关失败的更多信息。
load_failed
- 操作系统无法加载 NIF 库。bad_lib
- 该库不符合作为调用模块的 NIF 库的要求。load | upgrade
- 相应的库回调失败。reload
- 此模块实例已加载 NIF 库。先前已弃用的reload
功能已在 OTP 20 中删除。old_code
- 对load_nif/2
的调用是从已升级模块的旧代码中进行的;这是不允许的。
如果使用 -nifs()
属性(建议使用),则动态库中的所有 NIF 都必须声明为这样,load_nif/2
才能成功。另一方面,使用 -nifs()
属性声明的所有函数不必由动态库实现。这允许与目标无关的 Erlang 文件包含可能缺少 NIF 支持的函数的后备实现,具体取决于目标操作系统/硬件平台。
-spec loaded() -> [Module] when Module :: module().
返回所有已加载的 Erlang 模块(当前代码和旧代码),包括预加载的模块的列表。
另请参见 code
。
如果模块 Module
作为当前代码加载,则返回 true
;否则,返回 false
。它不会尝试加载该模块。
-spec pre_loaded() -> [module()].
返回在运行时系统中预加载的 Erlang 模块列表。
预加载模块是引导系统从磁盘加载第一个 Erlang 模块或使用 erl_boot_server
所需的 Erlang 模块。
-spec purge_module(Module) -> true when Module :: atom().
删除 Module
的旧代码。在使用此 BIF 之前,必须调用 check_process_code/2
以检查是否有进程在模块中执行旧代码。
警告
此 BIF 用于代码服务器(参见
code
),不应在其他地方使用。
变更
从 ERTS 8.0 (Erlang/OTP 19) 开始,任何仍在执行旧代码的残留进程都会被此函数杀死。在早期版本中,此类不正确的用法可能会导致更致命的失败,例如模拟器崩溃。
失败:如果 Module
没有旧代码,则返回 badarg
。
分布式 Erlang
强制断开节点的连接。
这样做会使节点 Node
看起来好像本地节点已崩溃。此 BIF 主要用于 Erlang 网络身份验证协议。
如果断开连接成功,则返回 true
,否则返回 false
。如果本地节点未启动,则返回 ignored
。
注意
此函数可能会在
nodedown
消息传递之前返回。
-spec dist_ctrl_get_data(DHandle) -> {Size, Data} | Data | none when Size :: non_neg_integer(), DHandle :: dist_handle(), Data :: iovec().
从本地节点获取要传递到远程节点的分布式通道数据。
分发通道由 DHandle
标识。如果没有任何数据可用,则返回原子 none
。可以通过调用 erlang:dist_ctrl_get_data_notification(DHandle)
来请求在有更多数据可用时通过消息通知。
有数据可用时返回的值取决于由 DHandle
标识的分发通道上配置的 get_size
选项的值。有关更多信息,请参阅 erlang:dist_ctrl_set_opt/3
函数的 get_size
选项的文档。
注意
只有注册为由
DHandle
标识的分发通道的分发控制器的进程才允许调用此函数。
此函数用于在使用进程作为分发控制器时实现备用分发载体。DHandle
通过回调 f_handshake_complete
检索。有关更多信息,请参阅 ERTS 用户指南 ➜ 如何为 Erlang 分发实现备用载体 ➜ 分发模块 文档。
-spec dist_ctrl_get_data_notification(DHandle) -> ok when DHandle :: dist_handle().
当有更多数据可使用 erlang:dist_ctrl_get_data(DHandle)
获取由 DHandle
标识的分布式通道时,请求通知。
当存在更多数据时,将向调用方发送消息 dist_data
。发送 dist_data
消息后,在再次调用 dist_ctrl_get_data_notification/1
函数之前,不会再发送 dist_data
消息。
注意
只有注册为由
DHandle
标识的分发通道的分发控制器的进程才允许调用此函数。
此函数用于在使用进程作为分发控制器时实现备用分发载体。DHandle
通过回调 f_handshake_complete
检索。有关更多信息,请参阅 ERTS 用户指南 ➜ 如何为 Erlang 分发实现备用载体 ➜ 分发模块 文档。
-spec dist_ctrl_get_opt(DHandle, get_size) -> Value when DHandle :: dist_handle(), Value :: boolean().
返回由 DHandle
标识的分布式通道上 get_size
选项的值。有关更多信息,请参阅 erlang:dist_ctrl_set_opt/3
函数的 get_size
选项的文档。
注意
只有注册为由
DHandle
标识的分发通道的分发控制器的进程才允许调用此函数。
此函数用于在使用进程作为分发控制器时实现备用分发载体。DHandle
通过回调 f_handshake_complete
检索。有关更多信息,请参阅 ERTS 用户指南 ➜ 如何为 Erlang 分发实现备用载体 ➜ 分发模块 文档。
-spec dist_ctrl_input_handler(DHandle, InputHandler) -> ok when DHandle :: dist_handle(), InputHandler :: pid().
为 DHandle
标识的分布式通道注册备用输入处理程序进程。
调用此函数后,InputHandler
是唯一允许使用 DHandle
调用 erlang:dist_ctrl_put_data(DHandle, Data)
的进程,该 DHandle
标识此分发通道。
注意
当由
DHandle
标识的分发通道的分发控制器是一个进程时,只有该进程允许调用此函数。当由DHandle
标识的分发通道的分发控制器是一个端口时,也允许调用此函数。在这种情况下,端口接收到的数据应传递给InputHandler
标识的进程,该进程应依次调用erlang:dist_ctrl_put_data/2
。
此函数用于实现备用分发载体。DHandle
通过回调 f_handshake_complete
检索。有关更多信息,请参阅 ERTS 用户指南 ➜ 如何为 Erlang 分发实现备用载体 ➜ 分发模块 文档。
-spec dist_ctrl_put_data(DHandle, Data) -> ok when DHandle :: dist_handle(), Data :: iodata().
将来自远程节点的分布式通道数据传递到本地节点。
注意
只有注册为由
DHandle
标识的分发通道的分发控制器的进程才允许调用此函数,除非已使用erlang:dist_ctrl_input_handler(DHandle, InputHandler)
注册了备用输入处理程序进程。如果已注册备用输入处理程序,则只有注册的输入处理程序进程才允许调用此函数。
此函数用于实现备用分发载体。DHandle
通过回调 f_handshake_complete
检索。有关更多信息,请参阅 ERTS 用户指南 ➜ 如何为 Erlang 分发实现备用载体 ➜ 分发模块 文档。
-spec dist_ctrl_set_opt(DHandle, get_size, Value) -> OldValue when DHandle :: dist_handle(), Value :: boolean(), OldValue :: boolean().
设置由 DHandle
标识的分布式通道上的 get_size
选项的值。
此选项控制对 erlang:dist_ctrl_get_data(DHandle) 的调用的返回值,其中 DHandle
等于设置此选项时使用的 DHandle
。当 get_size
选项为
false
- 如果存在分发数据,调用erlang:dist_ctrl_get_data(DHandle)
将只返回要通过通道传递的Data
。这是get_size
选项的默认值。true
- 如果存在分发数据,调用erlang:dist_ctrl_get_data(DHandle)
将返回要通过通道传递的Data
以及Data
的大小Size
(以字节为单位)。这将以{Size, Data}
的元组形式返回。
当通道关闭时,所有选项都将设置为默认值。
注意
只有注册为由
DHandle
标识的分发通道的分发控制器的进程才允许调用此函数。
此函数用于在使用进程作为分发控制器时实现备用分发载体。DHandle
通过回调 f_handshake_complete
检索。有关更多信息,请参阅 ERTS 用户指南 ➜ 如何为 Erlang 分发实现备用载体 ➜ 分发模块 文档。
-spec get_cookie() -> Cookie | nocookie when Cookie :: atom().
如果本地节点处于活动状态,则返回本地节点的 magic cookie,否则返回原子 nocookie
。此值由 set_cookie/1
设置。
如果本地节点处于活动状态,则返回节点 Node
的 magic cookie,否则返回原子 nocookie
。此值由 set_cookie/2
设置。
-spec is_alive() -> boolean().
如果本地节点处于活动状态(即,如果该节点可以成为分布式系统的一部分),则返回 true
,否则返回 false
。如果节点以以下方式启动,则该节点处于活动状态
如果节点通过调用 net_kernel:start/2
获取了名称,并且没有通过调用 net_kernel:stop/0
停止,则该节点也可以处于活动状态。
监视节点 Node
的状态。如果 Flag
为 true
,则启用监视。如果 Flag
为 false
,则关闭监视。
多次对同一个 Node
调用 monitor_node(Node, true)
不是错误;它会导致多个独立的监控实例。
如果 Node
失败或不存在,消息 {nodedown, Node}
将传递给该进程。 如果一个进程对 monitor_node(Node, true)
进行了两次调用,并且 Node
终止,则会向该进程传递两个 nodedown
消息。 如果没有与 Node
的连接,将尝试创建一个连接。 如果失败,则会传递 nodedown
消息。
nodedown
信号的传递与来自发生故障的节点的其他链接或监控信号的顺序无关。如果您需要保证在发送 nodedown
信号之前已传递来自远程节点的所有信号,则应使用 net_kernel:monitor_nodes/1
。
通过隐藏连接连接的节点可以像任何其他节点一样被监控。
失败: 如果本地节点未处于活动状态,则返回 notalive
。
-spec monitor_node(Node, Flag, Options) -> true when Node :: node(), Flag :: boolean(), Options :: [Option], Option :: allow_passive_connect.
行为与 monitor_node/2
相同,但允许指定一个额外的选项,即 allow_passive_connect
。
即使无法从此节点主动连接 (即,它被阻止),此选项允许 BIF 等待正常的网络连接超时时间来让 *被监控节点* 连接自身。只有使用内核选项 dist_auto_connect once
才能达到此状态。 如果未使用该选项,则选项 allow_passive_connect
无效。
注意
选项
allow_passive_connect
在内部使用,在网络拓扑和生效的内核选项预先已知的情况下,应用程序很少需要此选项。
失败: 如果本地节点未处于活动状态或选项列表格式不正确,则返回 badarg
。
-spec node() -> Node when Node :: node().
返回本地节点的名称。如果节点未处于活动状态,则返回 nonode@nohost
。
-spec nodes() -> Nodes when Nodes :: [node()].
返回通过正常连接(即,隐藏节点未列出)连接到此节点的所有节点的列表。与 nodes(visible) 相同。
-spec nodes(Arg) -> Nodes when Arg :: NodeType | [NodeType], NodeType :: visible | hidden | connected | this | known, Nodes :: [node()].
根据指定的参数返回节点列表。当参数为列表时,返回的结果是满足列表元素析取的节点列表。
NodeType
visible
- 通过普通连接连接到此节点的节点。hidden
- 通过隐藏连接连接到此节点的节点。connected
- 连接到此节点的所有节点。this
- 此节点。known
- 此节点已知的节点。也就是说,连接的节点以及此节点上的进程标识符、端口标识符和引用所引用的节点。已知节点的集合将被垃圾回收。请注意,此垃圾回收可能会延迟。有关更多信息,请参见erlang:system_info(delayed_node_table_gc)
。
一些等式: [node()] = nodes(this)
, nodes(connected) = nodes([visible, hidden])
, 和 nodes() = nodes(visible)
。
-spec nodes(Arg, InfoOpts) -> [NodeInfo] when NodeType :: visible | hidden | connected | this | known, Arg :: NodeType | [NodeType], InfoOpts :: #{connection_id => boolean(), node_type => boolean()}, NodeTypeInfo :: visible | hidden | this | known, ConnectionId :: undefined | integer(), Info :: #{connection_id => ConnectionId, node_type => NodeTypeInfo}, NodeInfo :: {node(), Info}.
返回 NodeInfo
元组的列表。
第一个元素是节点名称。要包含在列表中的节点由第一个参数 Arg
确定,其方式与 nodes(Arg)
相同。 NodeInfo
元组的第二个元素是一个映射,其中包含有关由第一个元素标识的节点的更多信息。此映射中存在的信息由作为第二个参数传递的 InfoOpts
映射确定。目前,允许在 InfoOpts
映射中使用以下关联
connection_id => boolean()
- 如果关联的值等于true
,则返回结果中的Info
映射将包含与值ConnectionId
关联的键connection_id
。如果ConnectionId
等于undefined
,则该节点未连接到调用者在其上执行的节点,或者该节点是调用者在其上执行的节点。如果ConnectionId
是整数,则该节点当前连接到调用者在其上执行的节点。整数连接标识符值与节点名称一起标识与该节点名称的节点的特定连接实例。连接标识符值是节点本地的。也就是说,在另一个节点上,连接标识符的值将*不*相同。如果一个连接被断开然后又重新连接,则该节点的连接的连接标识符值将发生更改。连接标识符的值数量有限,因此可能会看到不同实例使用相同的值,但这不太可能。两个连续连接实例之间的值如何变化是未定义的。
node_type => boolean()
- 如果关联的值等于true
,则返回结果中的Info
映射将包含与值NodeTypeInfo
关联的键node_type
。目前存在以下节点类型
示例
(a@localhost)1> nodes([this, connected], #{connection_id=>true, node_type=>true}).
[{c@localhost,#{connection_id => 13892108,node_type => hidden}},
{b@localhost,#{connection_id => 3067553,node_type => visible}},
{a@localhost,#{connection_id => undefined,node_type => this}}]
(a@localhost)2>
-spec set_cookie(Cookie) -> true when Cookie :: atom().
将本地节点的 magic cookie 设置为原子 Cookie
,这也是所有没有使用 set_cookie/2
显式设置 cookie 的节点的 cookie Cookie
。
有关更多信息,请参见系统文档中的 Erlang 参考手册中的 分布式 Erlang 部分。
您可以使用 get_cookie/0
获取此值。
失败: 如果本地节点未处于活动状态,则返回 function_clause
。
将 Node
的 magic cookie 设置为原子 Cookie
。如果 Node
是本地节点,则该函数会将所有其他节点(没有使用此函数显式设置 cookie 的节点)的 cookie 设置为 Cookie
。
有关更多信息,请参见系统文档中的 Erlang 参考手册中的 分布式 Erlang 部分。
您可以使用 get_cookie/1
获取此值。
失败: 如果本地节点未处于活动状态,则返回 function_clause
。
Erlang 项
-spec abs(Float) -> float() when Float :: float(); (Int) -> non_neg_integer() when Int :: integer().
返回一个整数或浮点数,它是 Float
或 Int
的算术绝对值。
例如
> abs(-3.33).
3.33
> abs(-3).
3
-spec append_element(Tuple1, Term) -> Tuple2 when Tuple1 :: tuple(), Tuple2 :: tuple(), Term :: term().
返回一个新元组,它比 Tuple1
多一个元素,并包含 Tuple1
中的元素,后跟 Term
作为最后一个元素。
在语义上等同于 list_to_tuple(tuple_to_list(Tuple1) ++ [Term])
,但速度更快。
例如
> erlang:append_element({one, two}, three).
{one,two,three}
-spec atom_to_binary(Atom, Encoding) -> binary() when Atom :: atom(), Encoding :: latin1 | unicode | utf8.
返回与 Atom
的文本表示形式相对应的二进制数据。
如果 Encoding
是 latin1
,则文本表示形式中的每个字符都存在一个字节。如果 Encoding
是 utf8
或 unicode
,则字符将使用 UTF-8 编码,其中字符可能需要多个字节。
变更
从 Erlang/OTP 20 开始,原子可以包含任何 Unicode 字符,并且如果
Atom
的文本表示形式包含 Unicode 字符 > 255,则atom_to_binary(Atom, latin1)
可能会失败。
示例
> atom_to_binary('Erlang', latin1).
<<"Erlang">>
返回与 Atom
的文本表示形式相对应的 Unicode 代码点列表。
例如
> atom_to_list('Erlang').
"Erlang"
> atom_to_list('你好').
[20320,22909]
有关如何将结果列表转换为不同格式的信息,请参见 unicode
。
-spec binary_part(Subject, PosLen) -> binary() when Subject :: binary(), PosLen :: {Start :: non_neg_integer(), Length :: integer()}.
提取由 PosLen
描述的二进制部分。
可以使用负长度来提取二进制末尾的字节。
例如
1> Bin = <<1,2,3,4,5,6,7,8,9,10>>.
2> binary_part(Bin,{byte_size(Bin), -5}).
<<6,7,8,9,10>>
失败: 如果 PosLen
以任何方式引用二进制之外的内容,则返回 badarg
。
Start
是基于零的,即
1> Bin = <<1,2,3>>
2> binary_part(Bin,{0,2}).
<<1,2>>
有关 PosLen
语义的详细信息,请参见 binary
。
-spec binary_part(Subject, Start, Length) -> binary() when Subject :: binary(), Start :: non_neg_integer(), Length :: integer().
-spec binary_to_atom(Binary, Encoding) -> atom() when Binary :: binary(), Encoding :: latin1 | unicode | utf8.
返回文本表示形式为 Binary
的原子。如果 Encoding
为 utf8
或 unicode
,则二进制数据必须包含有效的 UTF-8 序列。
变更
从 Erlang/OTP 20 开始,
binary_to_atom(Binary, utf8)
能够解码任何 Unicode 字符。早期版本如果二进制数据包含大于 255 的 Unicode 字符,则会失败。
注意
原子名称中允许的字符数量是有限制的。默认限制可以在效率指南(系统限制部分)中找到。
注意
可以存在的原子数量有一个可配置的限制,并且原子不会被垃圾回收。因此,建议考虑
binary_to_existing_atom/2
是否比binary_to_atom/2
更好的选择。默认限制可以在效率指南(系统限制部分)中找到。
示例
> binary_to_atom(<<"Erlang">>, latin1).
'Erlang'
> binary_to_atom(<<1024/utf8>>, utf8).
'Ѐ'
-spec binary_to_existing_atom(Binary, Encoding) -> atom() when Binary :: binary(), Encoding :: latin1 | unicode | utf8.
与 binary_to_atom/2
相同,但原子必须存在。
Erlang 系统对可以存在的原子总数有一个可配置的限制,并且原子不会被垃圾回收。因此,从来自不受信任来源的二进制数据(例如,从 Internet 获取的文件)创建大量原子是不安全的,例如,使用 binary_to_atom/2
。因此,当输入二进制数据来自不受信任的来源时,此函数是合适的选择。
当包含在已加载的 Erlang 模块中或以编程方式创建时(例如,通过 binary_to_atom/2
),原子存在于 Erlang 系统中。请参阅下一个注释,了解原子存在于 Erlang 模块的源代码中,但不存在于同一模块的编译版本中的示例。
失败:如果原子不存在,则返回 badarg
。
注意
请注意,编译器可能会优化掉原子。例如,编译器会将
atom_to_list(some_atom)
重写为"some_atom"
。如果该表达式是包含模块中唯一提及原子some_atom
的地方,则在加载模块时不会创建该原子,并且随后调用binary_to_existing_atom(<<"some_atom">>, utf8)
将失败。
注意
原子名称中允许的字符数量是有限制的。默认限制可以在效率指南(系统限制部分)中找到。
返回文本表示形式为 Binary
的浮点数。
例如
> binary_to_float(<<"2.2017764e+0">>).
2.2017764
浮点数字符串格式与 Erlang 浮点数文字的格式相同,只是不允许使用下划线。
失败:如果 Binary
包含错误的浮点数表示,则返回 badarg
。
返回文本表示形式为 Binary
的整数。
例如
> binary_to_integer(<<"123">>).
123
binary_to_integer/1
接受与 list_to_integer/1
相同的字符串格式。
失败:如果 Binary
包含错误的整数表示,则返回 badarg
。
返回以 Base
为基数的文本表示形式为 Binary
的整数。
例如
> binary_to_integer(<<"3FF">>, 16).
1023
binary_to_integer/2
接受与 list_to_integer/2
相同的字符串格式。
失败:如果 Binary
包含错误的整数表示,则返回 badarg
。
返回与 Binary
的字节相对应的整数列表。
-spec binary_to_list(Binary, Start, Stop) -> [byte()] when Binary :: binary(), Start :: pos_integer(), Stop :: pos_integer().
与 binary_to_list/1
相同,但返回一个整数列表,该列表对应于 Binary
中从位置 Start
到位置 Stop
的字节。二进制数据中的位置从 1 开始编号。
注意
此函数使用的基于 1 的二进制索引已弃用。 新代码应使用 STDLIB 中的
binary:bin_to_list/3
。模块binary
中的所有函数都一致地使用基于 0 的索引。
-spec binary_to_term(Binary) -> term() when Binary :: ext_binary().
返回 Erlang 术语,它是解码二进制对象 Binary
的结果,该对象必须按照 Erlang 外部术语格式进行编码。
> Bin = term_to_binary(hello).
<<131,100,0,5,104,101,108,108,111>>
> hello = binary_to_term(Bin).
hello
警告
当从不受信任的来源解码二进制数据时,不受信任的来源可能会以创建无法垃圾回收并导致拒绝服务攻击的资源(例如原子和远程引用)的方式提交数据。在这种情况下,请考虑使用带有
safe
选项的binary_to_term/2
。
另请参阅 term_to_binary/1
和 binary_to_term/2
。
-spec binary_to_term(Binary, Opts) -> term() | {term(), Used} when Binary :: ext_binary(), Opt :: safe | used, Opts :: [Opt], Used :: pos_integer().
等效于 binary_to_term(Binary)
,但可以配置为适合特殊用途。
允许的选项是
safe
- 从不受信任的来源接收二进制数据时使用此选项。启用后,它会阻止解码可用于攻击 Erlang 运行时的的数据。如果收到不安全的数据,解码将失败并返回
badarg
错误。这可以防止直接创建新原子、间接创建新原子(因为它们嵌入在某些结构中,例如进程标识符、引用和 fun)以及创建新的外部函数引用。所有这些资源都不会被垃圾回收,因此未经检查地创建它们可能会耗尽可用内存。
> binary_to_term(<<131,100,0,5,"hello">>, [safe]). ** exception error: bad argument > hello. hello > binary_to_term(<<131,100,0,5,"hello">>, [safe]). hello
警告
safe
选项确保 Erlang 运行时安全地处理数据,但它不能保证数据对您的应用程序是安全的。您必须始终验证来自不受信任来源的数据。如果二进制数据存储在不受信任的来源中或通过不受信任的来源传输,您还应考虑对其进行加密签名。used
- 将返回值更改为{Term, Used}
,其中Used
是实际从Binary
读取的字节数。> Input = <<131,100,0,5,"hello","world">>. <<131,100,0,5,104,101,108,108,111,119,111,114,108,100>> > {Term, Used} = binary_to_term(Input, [used]). {hello, 9} > split_binary(Input, Used). {<<131,100,0,5,104,101,108,108,111>>, <<"world">>}
失败:如果指定了 safe
并且解码了不安全的数据,则返回 badarg
。
另请参阅 term_to_binary/1
、binary_to_term/1
和 list_to_existing_atom/1
。
-spec bit_size(Bitstring) -> non_neg_integer() when Bitstring :: bitstring().
返回一个整数,该整数是 Bitstring
的位大小。
例如
> bit_size(<<433:16,3:3>>).
19
> bit_size(<<1,2,3>>).
24
返回与 Bitstring
的字节相对应的整数列表。
如果二进制数据中的位数不能被 8 整除,则列表的最后一个元素是一个包含剩余 1-7 位的位串。
例如
> bitstring_to_list(<<433:16>>).
[1,177]
> bitstring_to_list(<<433:16,3:3>>).
[1,177,<<3:3>>]
-spec byte_size(Bitstring) -> non_neg_integer() when Bitstring :: bitstring().
返回一个整数,该整数是包含 Bitstring
所需的字节数。也就是说,如果 Bitstring
中的位数不能被 8 整除,则结果字节数将向上取整。
例如
> byte_size(<<433:16,3:3>>).
3
> byte_size(<<1,2,3>>).
3
返回不小于 Number
的最小整数。
例如
> ceil(5.5).
6
-spec decode_packet(Type, Bin, Options) -> {ok, Packet, Rest} | {more, Length} | {error, Reason} when Type :: raw | 0 | 1 | 2 | 4 | asn1 | cdr | sunrm | fcgi | tpkt | line | http | http_bin | httph | httph_bin, Bin :: binary(), Options :: [Opt], Opt :: {packet_size, non_neg_integer()} | {line_length, non_neg_integer()}, Packet :: binary() | HttpPacket, Rest :: binary(), Length :: non_neg_integer() | undefined, Reason :: term(), HttpPacket :: HttpRequest | HttpResponse | HttpHeader | http_eoh | HttpError, HttpRequest :: {http_request, HttpMethod, HttpUri, HttpVersion}, HttpResponse :: {http_response, HttpVersion, integer(), HttpString}, HttpHeader :: {http_header, integer(), HttpField, UnmodifiedField :: HttpString, Value :: HttpString}, HttpError :: {http_error, HttpString}, HttpMethod :: 'OPTIONS' | 'GET' | 'HEAD' | 'POST' | 'PUT' | 'DELETE' | 'TRACE' | HttpString, HttpUri :: '*' | {absoluteURI, http | https, Host :: HttpString, Port :: inet:port_number() | undefined, Path :: HttpString} | {scheme, Scheme :: HttpString, HttpString} | {abs_path, HttpString} | HttpString, HttpVersion :: {Major :: non_neg_integer(), Minor :: non_neg_integer()}, HttpField :: 'Cache-Control' | 'Connection' | 'Date' | 'Pragma' | 'Transfer-Encoding' | 'Upgrade' | 'Via' | 'Accept' | 'Accept-Charset' | 'Accept-Encoding' | 'Accept-Language' | 'Authorization' | 'From' | 'Host' | 'If-Modified-Since' | 'If-Match' | 'If-None-Match' | 'If-Range' | 'If-Unmodified-Since' | 'Max-Forwards' | 'Proxy-Authorization' | 'Range' | 'Referer' | 'User-Agent' | 'Age' | 'Location' | 'Proxy-Authenticate' | 'Public' | 'Retry-After' | 'Server' | 'Vary' | 'Warning' | 'Www-Authenticate' | 'Allow' | 'Content-Base' | 'Content-Encoding' | 'Content-Language' | 'Content-Length' | 'Content-Location' | 'Content-Md5' | 'Content-Range' | 'Content-Type' | 'Etag' | 'Expires' | 'Last-Modified' | 'Accept-Ranges' | 'Set-Cookie' | 'Set-Cookie2' | 'X-Forwarded-For' | 'Cookie' | 'Keep-Alive' | 'Proxy-Connection' | HttpString, HttpString :: string() | binary().
根据 Type
指定的数据包协议解码二进制数据 Bin
。类似于带有选项 {packet,Type}
的套接字所做的数据包处理。
如果整个数据包都包含在 Bin
中,则会将其与二进制数据的其余部分一起作为 {ok,Packet,Rest}
返回。
如果 Bin
不包含整个数据包,则返回 {more,Length}
。Length
是数据包的预期总大小,如果预期数据包大小未知,则为 undefined
。decode_packet
可以再次调用,并添加更多数据。
如果数据包不符合协议格式,则返回 {error,Reason}
。
Type
s
raw | 0
- 不进行数据包处理。除非二进制数据为空,否则返回整个二进制数据。1 | 2 | 4
- 数据包由一个指定数据包中字节数的标头组成,后跟该数量的字节。标头的长度可以是一个、两个或四个字节;字节的顺序为大端。当返回数据包时,会剥离标头。line
- 数据包是以分隔符字节结尾的一行,默认分隔符是 latin-1 换行符。分隔符字节包含在返回的数据包中,除非根据选项line_length
截断了行。asn1 | cdr | sunrm | fcgi | tpkt
- 标头不会被剥离。数据包类型的含义如下
asn1
- ASN.1 BERsunrm
- Sun 的 RPC 编码cdr
- CORBA (GIOP 1.1)fcgi
- Fast CGItpkt
- TPKT 格式 [RFC1006]
http | httph | http_bin | httph_bin
- 超文本传输协议。返回的数据包的格式与前面描述的HttpPacket
一致。数据包可以是请求、响应、标头或标头结束标记。无效的行作为HttpError
返回。识别的请求方法和标头字段作为原子返回。其他则作为字符串返回。未识别的标头字段字符串的格式仅为首字母和连字符后的字母大写,例如
"Sec-Websocket-Key"
。标头字段名称也以UnmodifiedField
中的字符串形式返回,不进行任何转换或格式化。协议类型
http
仅用于预期HttpRequest
或HttpResponse
的第一行。后续调用应使用httph
来获取HttpHeader
,直到返回http_eoh
,这标记着标头的结束和任何后续消息体的开始。变体
http_bin
和httph_bin
返回字符串 (HttpString
) 作为二进制数据而不是列表。自 OTP 26.0 起,
Host
可以是用[]
括起来的 IPv6 地址,如 RFC2732 中定义的那样。
选项
{packet_size, integer() >= 0}
- 设置数据包主体允许的最大大小。如果数据包头指示数据包的长度大于允许的最大长度,则认为该数据包无效。默认为 0,表示没有大小限制。{line_length, integer() >= 0}
- 对于数据包类型line
,超过指示长度的行将被截断。如果未设置
packet_size
,则选项line_length
也适用于http*
数据包类型,作为选项packet_size
的别名。此用法仅用于向后兼容。{line_delimiter, 0 =< byte() =< 255}
- 对于数据包类型line
,设置分隔字节。默认值为拉丁字符$\n
。
示例
> erlang:decode_packet(1,<<3,"abcd">>,[]).
{ok,<<"abc">>,<<"d">>}
> erlang:decode_packet(1,<<5,"abcd">>,[]).
{more,6}
-spec delete_element(Index, Tuple1) -> Tuple2 when Index :: pos_integer(), Tuple1 :: tuple(), Tuple2 :: tuple().
返回一个新元组,该元组的 Index
处的元素已从元组 Tuple1
中删除。
例如
> erlang:delete_element(2, {one, two, three}).
{one,three}
-spec display(Term) -> true when Term :: term().
在标准输出上打印 Term
的文本表示形式。
警告
此 BIF 仅用于调试。打印的表示可能包含与 Erlang 中术语的高级表示不匹配的内部细节。
-spec element(N, Tuple) -> term() when N :: pos_integer(), Tuple :: tuple().
返回 Tuple
的第 N
个元素(从 1 开始编号)。
例如
> element(2, {a, b, c}).
b
-spec external_size(Term) -> non_neg_integer() when Term :: term().
在不进行编码的情况下,计算以 Erlang 外部术语格式编码的术语的最大字节大小。
以下条件始终适用
> Size1 = byte_size(term_to_binary(Term)),
> Size2 = erlang:external_size(Term),
> true = Size1 =< Size2.
true
这等效于调用
erlang:external_size(Term, [])
-spec external_size(Term, Options) -> non_neg_integer() when Term :: term(), Options :: [compressed | {compressed, Level :: 0..9} | deterministic | {minor_version, Version :: 0..2} | local].
在不进行编码的情况下,计算以 Erlang 外部术语格式编码的术语的最大字节大小。
以下条件始终适用
> Size1 = byte_size(term_to_binary(Term, Options)),
> Size2 = erlang:external_size(Term, Options),
> true = Size1 =< Size2.
true
选项 {minor_version, Version}
指定浮点数的编码方式。有关详细描述,请参阅 term_to_binary/2
。
通过将 Number
转换为浮点数来返回浮点数。
例如
> float(55).
55.0
注意
如果在 guard 中的顶层使用,它会测试参数是否为浮点数;为清楚起见,请改用
is_float/1
。当
float/1
在 guard 的表达式中使用时,例如 'float(A) == 4.0
',它会按照前面描述的方式转换数字。
-spec float_to_binary(Float, Options) -> binary() when Float :: float(), Options :: [Option], Option :: {decimals, Decimals :: 0..253} | {scientific, Decimals :: 0..249} | compact | short.
返回与 Float
的文本表示形式相对应的二进制数据,使用固定小数点格式。
Options
的行为方式与 float_to_list/2
相同。
例如
> float_to_binary(7.12, [{decimals, 4}]).
<<"7.1200">>
> float_to_binary(7.12, [{decimals, 4}, compact]).
<<"7.12">>
> float_to_binary(7.12, [{scientific, 3}]).
<<"7.120e+00">>
> float_to_binary(7.12, [short]).
<<"7.12">>
> float_to_binary(0.1+0.2, [short]).
<<"0.30000000000000004">>
> float_to_binary(0.1+0.2)
<<"3.00000000000000044409e-01">>
-spec float_to_list(Float, Options) -> string() when Float :: float(), Options :: [Option], Option :: {decimals, Decimals :: 0..253} | {scientific, Decimals :: 0..249} | compact | short.
返回与 Float
的文本表示形式相对应的字符串,使用固定小数点格式。
可用选项
- 如果指定了选项
decimals
,则返回值最多包含小数点后的Decimals
位数字。如果数字不适合 256 字节的内部静态缓冲区,则该函数抛出badarg
。 - 如果指定了选项
compact
,则列表末尾的尾随零将被截断。此选项仅在与选项decimals
一起使用时才有意义。 - 如果指定了选项
scientific
,则浮点数将使用科学计数法格式化,精度为Decimals
位。 - 如果指定了选项
short
,则浮点数将使用最小的位数进行格式化,同时仍然保证F =:= list_to_float(float_to_list(F, [short]))
。当浮点数在范围 (-2⁵³, 2⁵³) 内时,将使用产生最小字符数的表示法(科学计数法或普通十进制表示法)。超出范围 (-2⁵³, 2⁵³) 的浮点数始终使用科学计数法进行格式化,以避免在执行算术运算时产生令人困惑的结果。 - 如果
Options
为[]
,则该函数的行为与float_to_list/1
相同。
示例
> float_to_list(7.12, [{decimals, 4}]).
"7.1200"
> float_to_list(7.12, [{decimals, 4}, compact]).
"7.12"
> float_to_list(7.12, [{scientific, 3}]).
"7.120e+00"
> float_to_list(7.12, [short]).
"7.12"
> float_to_list(0.1+0.2, [short]).
"0.30000000000000004"
> float_to_list(0.1+0.2)
"3.00000000000000044409e-01"
在最后一个示例中,float_to_list(0.1+0.2)
的计算结果为 "3.00000000000000044409e-01"
。 造成这种情况的原因在 浮点数表示问题 中进行了解释。
返回不大于 Number
的最大整数。
例如
> floor(-10.5).
-11
-spec fun_info(Fun) -> [{Item, Info}] when Fun :: function(), Item :: arity | env | index | name | module | new_index | new_uniq | pid | type | uniq, Info :: term().
返回包含有关函数 Fun
的信息的列表。每个列表元素都是一个元组。元组的顺序未定义,并且可以在将来的版本中添加更多元组。
警告
此 BIF 主要用于调试,但有时在需要验证 fun 的元数(例如)的库函数中也很有用。
两种类型的 fun 具有略微不同的语义
- 由
fun M:F/A
创建的 fun 称为外部 fun。调用它将始终调用模块M
最新代码中元数为A
的函数F
。请注意,当创建 funfun M:F/A
时,甚至不需要加载模块M
。 - 所有其他 fun 都称为本地 fun。当调用本地 fun 时,将调用创建该 fun 的相同版本的代码(即使已加载模块的较新版本)。
以下元素始终存在于本地和外部 fun 的列表中
{type, Type}
-Type
是local
或external
。{module, Module}
-Module
(一个原子) 是模块名称。如果
Fun
是一个本地 fun,则Module
是定义该 fun 的模块。如果
Fun
是一个外部 fun,则Module
是该 fun 引用的模块。{name, Name}
-Name
(一个原子) 是函数名称。如果
Fun
是一个本地 fun,则Name
是实现该 fun 的本地函数的名称。(此名称由编译器生成,仅供参考。由于它是一个本地函数,因此无法直接调用它。)如果当前未为该 fun 加载任何代码,则返回[]
而不是原子。如果
Fun
是一个外部 fun,则Name
是该 fun 引用的已导出函数的名称。{arity, Arity}
-Arity
是调用该 fun 时使用的参数数量。{env, Env}
-Env
(一个列表) 是该 fun 的环境或自由变量。对于外部 fun,返回的列表始终为空。
如果 Fun
是本地 fun,则以下元素仅存在于列表中
{pid, Pid}
-Pid
是本地节点上init
进程的进程标识符。变更
从 Erlang/OTP 27 开始,无论 fun 最初是在哪个进程或节点上创建的,
Pid
始终指向本地init
进程。请参阅 即将到来的潜在不兼容性。
{index, Index}
-Index
(一个整数) 是模块 fun 表中的索引。{new_index, Index}
-Index
(一个整数) 是模块 fun 表中的索引。{new_uniq, Uniq}
-Uniq
(一个二进制数据) 是此 fun 的唯一值。它从整个模块的编译代码中计算得出。{uniq, Uniq}
-Uniq
(一个整数) 是此 fun 的唯一值。从 Erlang/OTP R15 开始,此整数从整个模块的编译代码中计算得出。在 Erlang/OTP R15 之前,此整数仅基于 fun 的主体。
-spec fun_info(Fun, Item) -> {Item, Info} when Fun :: function(), Item :: fun_info_item(), Info :: term().
以 {Item,Info}
的形式返回 Fun
的由 Item
指定的信息。
对于任何 fun,Item
可以是原子 module
、name
、arity
、env
或 type
中的任何一个。
对于本地 fun,Item
也可以是原子 index
、new_index
、new_uniq
、uniq
和 pid
中的任何一个。对于外部 fun,任何这些项的值始终是原子 undefined
。
请参阅 erlang:fun_info/1
。
返回表示创建 Fun
的代码的 String
。
如果 Fun
是由 fun 表达式 以 fun ModuleName:FuncName/Arity
的形式创建的,则 String
具有以下形式
"fun ModuleName:FuncName/Arity"
当 Fun
是从其他类型的 fun 表达式 创建时,String
的形式取决于 fun 表达式是在执行编译代码时执行的,还是在执行未编译代码(未编译的 escript、Erlang shell 以及由 erl_eval 模块执行的其他代码)时执行的。
编译代码 -
"#Fun<M.I.U>"
,其中 M、I 和 U 对应于erlang:fun_info(Fun)
结果中名为module
、index
和uniq
的值。未编译的代码 - 通过
fun_to_list/1
,所有从未编译代码中的 fun 表达式创建且具有相同元数的 fun 都被映射到同一个列表。
注意
通常,不能使用
fun_to_list/1
来检查两个 fun 是否相等,因为fun_to_list/1
不会将 fun 的环境考虑在内。有关如何获取 fun 的环境,请参阅erlang:fun_info/1
。
变更
fun_to_list/1
的输出在不同的 Erlang 实现之间可能有所不同,并且在未来的版本中可能会更改。
示例
-module(test).
-export([add/1, add2/0, fun_tuple/0]).
add(A) -> fun(B) -> A + B end.
add2() -> fun add/1.
fun_tuple() -> {fun() -> 1 end, fun() -> 1 end}.
> {fun test:add/1, test:add2()}.
{fun test:add/1,#Fun<test.1.107738983>}
解释:fun test:add/1
是可升级的,但 test:add2()
不可升级。
> {test:add(1), test:add(42)}.
{#Fun<test.0.107738983>,#Fun<test.0.107738983>}
解释:test:add(1)
和 test:add(42)
具有相同的字符串表示形式,因为环境未被考虑在内。
>test:fun_tuple().
{#Fun<test.2.107738983>,#Fun<test.3.107738983>}
解释:字符串表示形式不同,因为 fun 来自不同的 fun 表达式。
> {fun() -> 1 end, fun() -> 1 end}. >
{#Fun<erl_eval.45.97283095>,#Fun<erl_eval.45.97283095>}
解释:所有从这种形式的 fun 表达式创建的、具有相同元数的、未编译代码中的 fun,都会通过 fun_to_list/1
映射到同一个列表。
-spec hd(List) -> Head when List :: nonempty_maybe_improper_list(), Head :: term().
返回 List
的头部,即第一个元素。
它适用于非正常列表。
示例
> hd([1,2,3,4,5]).
1
> hd([first, second, third, so_on | improper_end]).
first
失败:如果 List
是空列表 []
,则返回 badarg
。
-spec insert_element(Index, Tuple1, Term) -> Tuple2 when Index :: pos_integer(), Tuple1 :: tuple(), Tuple2 :: tuple(), Term :: term().
返回一个新元组,其中元素 Term
插入到元组 Tuple1
中的位置 Index
。从位置 Index
开始的所有元素都将在新元组 Tuple2
中向上移动一步。
例如
> erlang:insert_element(2, {one, two, three}, new).
{one,new,two,three}
返回与 Integer
的文本表示形式相对应的二进制数据。
例如
> integer_to_binary(77).
<<"77">>
返回与以 Base
为基数的 Integer
的文本表示形式相对应的二进制数据。
例如
> integer_to_binary(1023, 16).
<<"3FF">>
返回与 Integer
的文本表示形式相对应的字符串。
例如
> integer_to_list(77).
"77"
返回与以 Base
为基数的 Integer
的文本表示形式相对应的字符串。
例如
> integer_to_list(1023, 16).
"3FF"
-spec iolist_size(Item) -> non_neg_integer() when Item :: iolist() | binary().
返回一个整数,该整数是 iolist_to_binary(Item)
的结果二进制数据的大小(以字节为单位)。
例如
> iolist_size([1,2|<<3,4>>]).
4
返回一个由 IoListOrBinary
中的整数和二进制数据组成的二进制数据。
例如
> Bin1 = <<1,2,3>>.
<<1,2,3>>
> Bin2 = <<4,5>>.
<<4,5>>
> Bin3 = <<6>>.
<<6>>
> iolist_to_binary([Bin1,1,[2,3,Bin2],4|Bin3]).
<<1,2,3,1,2,3,4,5,4,6>>
返回一个由 IoListOrBinary
中的整数和二进制数据组成的 iovec。当你想要展平一个 iolist,但不需要单个二进制数据时,此函数非常有用。这对于将数据传递给 NIF 函数(例如 enif_inspect_iovec
)或进行更高效的消息传递非常有用。与 iolist_to_binary/1
相比,使用此函数的优点是它不必复制 堆外二进制数据。
例如
> Bin1 = <<1,2,3>>.
<<1,2,3>>
> Bin2 = <<4,5>>.
<<4,5>>
> Bin3 = <<6>>.
<<6>>
%% If you pass small binaries and integers it works as iolist_to_binary
> erlang:iolist_to_iovec([Bin1,1,[2,3,Bin2],4|Bin3]).
[<<1,2,3,1,2,3,4,5,4,6>>]
%% If you pass larger binaries, they are split and returned in a form
%% optimized for calling the C function writev.
> erlang:iolist_to_iovec([<<1>>,<<2:8096>>,<<3:8096>>]).
[<<1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,...>>,
<<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
...>>,
<<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...>>]
如果 Term
是原子,则返回 true
,否则返回 false
。
如果 Term
是二进制数据,则返回 true
,否则返回 false
。
一个二进制总是包含完整数量的字节。
如果 Term
是位串(包括二进制数据),则返回 true
,否则返回 false
。
如果 Term
是原子 true
或原子 false
(即布尔值),则返回 true
。否则返回 false
。
如果 Term
是浮点数,则返回 true
,否则返回 false
。
如果 Term
是一个 fun,则返回 true
,否则返回 false
。
如果 Term
是一个可以使用 Arity
个参数应用的 fun,则返回 true
,否则返回 false
。
如果 Term
是整数,则返回 true
,否则返回 false
。
如果 Term
是包含零个或多个元素的列表,则返回 true
,否则返回 false
。
如果 Term
是一个映射,则返回 true
,否则返回 false
。
如果映射 Map
包含 Key
,则返回 true
,如果它不包含 Key
,则返回 false
。
如果 Map
不是一个映射,则调用会失败并抛出 {badmap,Map}
异常。
示例
> Map = #{"42" => value}.
#{"42" => value}
> is_map_key("42",Map).
true
> is_map_key(value,Map).
false
如果 Term
是整数或浮点数,则返回 true
。否则返回 false
。
如果 Term
是进程标识符,则返回 true
,否则返回 false
。
如果 Term
是端口标识符,则返回 true
,否则返回 false
。
如果 Term
是一个元组,且它的第一个元素是 RecordTag
,则返回 true
。否则返回 false
。
注意
通常,编译器会特殊处理对
is_record/2
的调用。它会生成代码来验证Term
是一个元组,其第一个元素是RecordTag
,并且大小正确。但是,如果RecordTag
不是字面原子,则会改为调用 BIFis_record/2
,并且不会验证元组的大小。
如果 RecordTag
是字面原子,则允许在 guard 测试中使用。
-spec is_record(Term, RecordTag, Size) -> boolean() when Term :: term(), RecordTag :: atom(), Size :: non_neg_integer().
RecordTag
必须是原子。
如果 Term
是一个元组,其第一个元素是 RecordTag
,并且大小是 Size
,则返回 true
。否则返回 false
。
如果 RecordTag
是字面原子,并且 Size
是字面整数,则允许在 guard 测试中使用。
注意
记录此 BIF 是为了完整性。通常应该使用
is_record/2
。
如果 Term
是引用,则返回 true
,否则返回 false
。
如果 Term
是元组,则返回 true
,否则返回 false
。
-spec length(List) -> non_neg_integer() when List :: [term()].
返回 List
的长度。
例如
> length([1,2,3,4,5,6,7,8,9]).
9
返回文本表示形式为 String
的原子。
从 Erlang/OTP 20 开始,String
可以包含任何 Unicode 字符。早期版本只允许 ISO-latin-1 字符,因为实现不允许 255 以上的 Unicode 字符。
注意
原子名称中允许的字符数量是有限的。默认限制可以在效率指南(系统限制部分)中找到。
注意
可以存在的原子数量有一个可配置的限制,并且原子不会被垃圾回收。因此,建议考虑
list_to_existing_atom/1
是否比list_to_atom/1
更好的选择。默认限制可以在效率指南(系统限制部分)中找到。
示例
> list_to_atom("Erlang").
'Erlang'
返回一个由 IoList
中的整数和二进制数据组成的二进制数据。
例如
> Bin1 = <<1,2,3>>.
<<1,2,3>>
> Bin2 = <<4,5>>.
<<4,5>>
> Bin3 = <<6>>.
<<6>>
> list_to_binary([Bin1,1,[2,3,Bin2],4|Bin3]).
<<1,2,3,1,2,3,4,5,4,6>>
-spec list_to_bitstring(BitstringList) -> bitstring() when BitstringList :: bitstring_list().
返回一个由 BitstringList
中的整数和位串组成的位串。(BitstringList
中的最后一个尾部允许是位串。)
例如
> Bin1 = <<1,2,3>>.
<<1,2,3>>
> Bin2 = <<4,5>>.
<<4,5>>
> Bin3 = <<6,7:4>>.
<<6,7:4>>
> list_to_bitstring([Bin1,1,[2,3,Bin2],4|Bin3]).
<<1,2,3,1,2,3,4,5,4,6,7:4>>
返回文本表示形式为 String
的原子,但前提是该原子已存在。如果原子是通过运行时系统加载代码或创建包含该原子的项而创建的,则该原子存在。
失败:如果不存在文本表示形式为 String
的原子,则返回 badarg
。
注意
请注意,编译器可能会优化掉原子。例如,编译器会将
atom_to_list(some_atom)
重写为"some_atom"
。如果该表达式是包含模块中唯一提及原子some_atom
的地方,则当加载模块时不会创建该原子,并且后续调用list_to_existing_atom("some_atom")
将会失败。
返回文本表示形式为 String
的浮点数。
例如
> list_to_float("2.2017764e+0").
2.2017764
浮点数字符串格式与 Erlang 浮点数文字的格式相同,只是不允许使用下划线。
失败:如果 String
包含浮点数的错误表示,则返回 badarg
。
返回文本表示形式为 String
的整数。
例如
> list_to_integer("123").
123
> list_to_integer("-123").
-123
> list_to_integer("+123234982304982309482093833234234").
123234982304982309482093833234234
String
必须至少包含一个数字字符,并且可以有一个可选的前缀,由单个 "+
" 或 "-
" 字符组成(也就是说,String
必须匹配正则表达式 "^[+-]?[0-9]+$"
)。
失败:如果 String
包含整数的错误表示,则返回 badarg
。
返回以 Base
为基数的文本表示形式为 String
的整数。
例如
> list_to_integer("3FF", 16).
1023
> list_to_integer("+3FF", 16).
1023
> list_to_integer("3ff", 16).
1023
> list_to_integer("3fF", 16).
1023
> list_to_integer("-3FF", 16).
-1023
例如,当 Base
为 16 时,String
必须匹配正则表达式 "^[+-]?([0-9]|[A-F]|[a-f])+$"
。
失败:如果 String
包含整数的错误表示,则返回 badarg
。
返回文本表示形式为 String
的进程标识符。
例如
> list_to_pid("<0.4.1>").
<0.4.1>
失败:如果 String
包含进程标识符的错误表示,则返回 badarg
。
警告
此 BIF 用于调试,不应在应用程序中使用。
返回文本表示形式为 String
的端口标识符。
例如
> list_to_port("#Port<0.4>").
#Port<0.4>
失败:如果 String
包含端口标识符的错误表示,则返回 badarg
。
警告
此 BIF 用于调试,不应在应用程序中使用。
返回文本表示形式为 String
的引用。
例如
> list_to_ref("#Ref<0.4192537678.4073193475.71181>").
#Ref<0.4192537678.4073193475.71181>
失败:如果 String
包含引用的错误表示,则返回 badarg
。
警告
此 BIF 用于调试,不应在应用程序中使用。
返回与 List
对应的元组,例如
> list_to_tuple([share, ['Ericsson_B', 163]]).
{share, ['Ericsson_B', 163]}
List
可以包含任何 Erlang 项。
-spec make_ref() -> reference().
返回一个唯一引用。该引用在连接的节点之间是唯一的。
警告
在 OTP 23 之前的版本中,当一个节点使用相同的节点名称多次重启时,在较新节点上创建的引用可能会被误认为是使用相同节点名称的较旧节点上创建的引用。
创建一个指定 Arity
的新元组,其中所有元素均为 InitialValue
。
例如
> erlang:make_tuple(4, []).
{[],[],[],[]}
-spec make_tuple(Arity, DefaultValue, InitList) -> tuple() when Arity :: arity(), DefaultValue :: term(), InitList :: [{Position :: pos_integer(), term()}].
创建一个大小为 Arity
的元组,其中每个元素的值为 DefaultValue
,然后从 InitList
中填充值。
InitList
中的每个列表元素都必须是一个二元组,其中第一个元素是新创建的元组中的位置,第二个元素是任何项。如果一个位置在列表中出现多次,则使用最后一次出现的项。
例如
> erlang:make_tuple(5, [], [{2,ignored},{5,zz},{2,aa}]).
{[],aa,[],[],zz}
如果 Map
包含 Key
,则返回与 Key
关联的值 Value
。
如果 Map
不是 map,则调用会失败并抛出 {badmap,Map}
异常;如果 Key
没有关联的值,则会抛出 {badkey,Key}
异常。
示例
> Key = 1337,
Map = #{42 => value_two,1337 => "value one","a" => 1},
map_get(Key,Map).
"value one"
-spec map_size(Map) -> non_neg_integer() when Map :: map().
返回一个整数,它是 Map
中键值对的数量。
例如
> map_size(#{a=>1, b=>2, c=>3}).
3
-spec match_spec_test(MatchAgainst, MatchSpec, Type) -> TestResult when MatchAgainst :: [term()] | tuple(), MatchSpec :: term(), Type :: table | trace, TestResult :: {ok, term(), [return_trace], [{error | warning, string()}]} | {error, [{error | warning, string()}]}.
测试在调用 ets:select/2
和 trace:function/4
中使用的匹配规范。
该函数测试匹配规范的“语法”正确性,并针对对象运行匹配规范。如果匹配规范包含错误,则返回元组 {error, Errors}
,其中 Errors
是自然语言描述的匹配规范错误列表。
如果 Type
是 table
,则要匹配的对象必须是元组。然后,函数返回 {ok,Result,[],Warnings}
,其中 Result
是真正的 ets:select/2
调用中的结果,如果匹配规范与对象元组不匹配,则返回 false
。
如果 Type
是 trace
,则要匹配的对象必须是列表。该函数返回 {ok, Result, Flags, Warnings}
,其中 Result
是以下之一:
- 如果需要发出跟踪消息,则返回
true
- 如果不需要发出跟踪消息,则返回
false
- 要附加到跟踪消息的消息项
Flags
是一个列表,其中包含要启用的所有跟踪标志,当前只有 return_trace
。
这是一个有用的调试和测试工具,尤其是在编写复杂的匹配规范时。
另请参阅 ets:test_ms/2
。
返回 Term1
和 Term2
中较大的一个。如果使用 ==
运算符比较时,两个项相等,则返回 Term1
。
表达式部分包含 ==
运算符的描述以及项的排序方式。
示例
> max(1, 2).
2
> max(1.0, 1).
1.0
> max(1, 1.0).
1
> max("abc", "b").
"b"
变更
自 Erlang/OTP 26 起,允许在保护测试中使用。
返回 Term1
和 Term2
中较小的一个。如果使用 ==
运算符比较时,两个项相等,则返回 Term1
。
表达式部分包含 ==
运算符的描述以及项的排序方式。
示例
> min(1, 2).
1
> min(1.0, 1).
1.0
> min(1, 1.0).
1
> min("abc", "b").
"abc"
变更
自 Erlang/OTP 26 起,允许在保护测试中使用。
返回 Arg
的来源节点。Arg
可以是进程标识符、引用或端口。如果 Arg
来自本地节点,并且本地节点未处于活动状态,则返回 nonode@nohost
。
-spec phash2(Term) -> Hash when Term :: term(), Hash :: non_neg_integer().
等效于 phash2/2
。
-spec phash2(Term, Range) -> Hash when Term :: term(), Range :: pos_integer(), Hash :: non_neg_integer().
可移植的哈希函数,它为相同的 Erlang 项提供相同的哈希值,而与机器架构和 ERTS 版本无关。
该函数返回 Term
在 0..Range-1
范围内的哈希值。Range
的最大值为 2^32。如果没有参数 Range
,则返回 0..2^27-1 范围内的值。
此 BIF 始终用于散列项。它比 phash/2
更好地分配小整数,并且对于大数字和二进制文件来说速度更快。
请注意,范围 0..Range-1
与 phash/2
的范围 1..Range
不同。
返回与 Pid
的文本表示形式对应的字符串。
例如
> erlang:pid_to_list(self()).
"<0.85.0>"
注意
节点的创建不包含在
Pid
的列表表示中。这意味着具有特定名称的节点的不同化身中的进程可以获得相同的列表表示。
返回与端口标识符 Port
的文本表示形式对应的字符串。
返回与 Ref
的文本表示形式对应的字符串。
警告
此 BIF 用于调试,不应在应用程序中使用。
通过舍入 Number
返回一个整数。
例如
round(42.1).
42
round(5.5).
6
round(-5.5).
-6
round(36028797018963969.0).
36028797018963968
在最后一个示例中,round(36028797018963969.0)
的计算结果为 36028797018963968
。原因是数字 36028797018963969.0
不能精确地表示为浮点值。相反,浮点文字表示为 36028797018963968.0
,它是最接近的可精确表示为浮点值的数字。有关更多信息,请参阅浮点数的表示。
-spec setelement(Index, Tuple1, Value) -> Tuple2 when Index :: pos_integer(), Tuple1 :: tuple(), Tuple2 :: tuple(), Value :: term().
返回一个元组,它是参数 Tuple1
的副本,其中由整数参数 Index
指定的元素(第一个元素的索引为 1)被参数 Value
替换。
例如
> setelement(2, {10, green, bottles}, red).
{10,red,bottles}
-spec size(Item) -> non_neg_integer() when Item :: tuple() | binary().
返回元组中的元素数量或二进制数据或位串中的字节数。
例如
> size({morni, mulle, bwange}).
3
> size(<<11, 22, 33>>).
3
对于位串,返回完整字节数。也就是说,如果位串中的位数不能被 8 整除,则结果字节数将向下舍入。
另请参阅 tuple_size/1
、byte_size/1
和 bit_size/1
。
-spec split_binary(Bin, Pos) -> {binary(), binary()} when Bin :: binary(), Pos :: non_neg_integer().
返回一个元组,其中包含将 Bin
在位置 Pos
处拆分为两部分的结果二进制数据。
这不是破坏性操作。操作后,总共有三个二进制文件。
例如
> B = list_to_binary("0123456789").
<<"0123456789">>
> byte_size(B).
10
> {B1, B2} = split_binary(B,3).
{<<"012">>,<<"3456789">>}
> byte_size(B1).
3
> byte_size(B2).
7
-spec term_to_binary(Term) -> ext_binary() when Term :: term().
返回一个二进制数据对象,它是根据 Erlang 外部项格式 对 Term
进行编码的结果。
这可以用于各种目的,例如,以有效的方式将项写入文件,或将 Erlang 项发送到分布式 Erlang 不支持的某些类型的通信通道。
> Bin = term_to_binary(hello).
<<131,100,0,5,104,101,108,108,111>>
> hello = binary_to_term(Bin).
hello
另请参阅 binary_to_term/1
。
注意
不保证此函数会为同一项返回相同的编码表示。
-spec term_to_binary(Term, Options) -> ext_binary() when Term :: term(), Options :: [compressed | {compressed, Level :: 0..9} | deterministic | {minor_version, Version :: 0..2} | local].
返回一个二进制数据对象,它是根据 Erlang 外部项格式对 Term
进行编码的结果。
当前支持的选项
compressed
- 压缩外部项格式。自 Erlang/OTP R7B 起,binary_to_term/1
会自动识别压缩格式。{compressed, Level}
- 将外部项格式压缩到给定的级别。压缩级别由Level
指定,Level
是 0..9 范围内的整数,其中:0
- 不进行压缩(与不提供compressed
选项相同)。1
- 耗时最少,但可能不如更高级别的压缩效果好。6
- 提供compressed
选项时的默认级别。9
- 耗时最长,并尝试生成较小的结果。请注意前一句中的“尝试”;根据输入项的不同,9 级压缩可能会或不会产生比 1 级压缩更小的结果。
{minor_version, Version}
(自 R11B-4 起)
此选项可用于控制某些编码细节。Version
的有效值包括:0
- 浮点数使用文本表示形式进行编码。可以用 latin1 字符串表示的原子使用 latin1 进行编码,而只有不能用 latin1 表示的原子才使用 utf8 进行编码。
1
- 浮点数以更节省空间且精确的方式进行编码(即以 64 位 IEEE 格式,而不是转换为文本表示形式)。从 Erlang/OTP R11B-4 开始,binary_to_term/1
可以解码此表示形式。可以用 latin1 字符串表示的原子使用 latin1 进行编码,而只有不能用 latin1 表示的原子才使用 utf8 进行编码。
2
- 这是自 Erlang/OTP 26.0 起的默认值。原子无条件地使用 utf8 进行编码。自 R16B 起的 Erlang/OTP 系统可以解码此表示形式。
deterministic
(自 OTP 24.1 起)
此选项可用于确保在 Erlang/OTP 的同一主要版本中,对于同一项返回相同的编码表示形式。仍然无法保证编码表示形式在 Erlang/OTP 的主要版本之间保持不变。此选项不能与
local
选项组合使用。local
(自 OTP 26.0 起)
此选项将导致将Term
编码为外部项格式的替代本地版本,当由同一运行时系统实例解码时,即使当前运行时系统实例的节点名称和/或创建在编码和解码之间已更改,也会生成与编码项相同的项。在不使用local
选项进行编码时,如果当前运行时系统实例的节点名称和/或创建在编码和解码之间发生更改,则诸如 pids、ports 和 references 之类的本地标识符将不相同。这是因为此类标识符通过节点名称和创建来引用特定节点。当使用
-name
或-sname
命令行参数启动运行时系统时,运行时系统实例的节点名称和创建会发生更改。请注意,分发的实际启动发生在启动阶段的其他代码开始执行之后。也可以通过调用net_kernel:start/2
来启动分发,并通过调用net_kernel:stop/1
来停止分发(如果它不是通过命令行启动的)。解码使用
local
选项编码的项(例如使用binary_to_term()
)将尝试验证该项实际上是否由同一运行时系统实例编码,并且如果编码是由另一个运行时系统实例执行的,则绝大多数情况下会失败。但是,您不应该信任此验证在所有情况下都有效。您应该确保仅在与编码项的 Erlang 运行时系统实例相同的实例上解码使用local
选项编码的项。由于只有使用
local
选项编码项的运行时系统才能解码该项,因此本地编码通常与其他内容拼接在一起,以生成对local
编码源的回复。如果使用local
选项编码的项被剥离了前导版本号,则可以在使用例如 ei 以外部项格式进行编码时,将其添加为较大项的一部分(例如作为元组中的元素)。在ei
的情况下,您可以使用ei_decode_version()
剥离其版本号,然后使用例如ei_x_append_buf()
将剩余的本地编码添加到您正在编码的内容中。何时需要使用
local
选项的一个很好的示例是,当您想从进程向端口 驱动程序发出请求,并在接收回复时利用 选择性接收优化时。在这种情况下,您需要创建一个引用,使用local
选项在外部项格式上序列化该引用,在请求中将其传递给驱动程序,然后在选择性接收中等待与该引用匹配的回复消息。驱动程序应使用erl_drv_output_term()
或erl_drv_send_term()
,使用请求中先前在外部项格式上接收的引用的项类型ERL_DRV_EXT2TERM
来发送回复。请注意,使用此功能的项类型ERL_DRV_EXT2TERM
时,不应从本地编码中剥离前导版本号。如果在此示例中不使用local
选项对引用进行编码,并且在请求进行期间启动或停止分发,则发出请求的进程将无限期地挂起,因为回复消息中的引用永远不会匹配。此选项不能与
deterministic
选项组合使用。有关详细信息,请参阅外部项格式文档中的
LOCAL_EXT
标签。
另请参阅 binary_to_term/1
。
返回根据 Erlang 外部项格式编码的 Term
,作为 ext_iovec/0
。
此函数产生的编码与 term_to_binary/1
相同,但返回类型不同。调用 iolist_to_binary(term_to_iovec(Term))
将产生与调用 term_to_binary(Term)
完全相同的结果。
term_to_iovec()
是对 term_to_binary()
提供的功能的纯优化。term_to_iovec()
例如可以直接引用堆外二进制文件,而不是将二进制数据复制到结果中。
另请参阅 term_to_binary/1
。
-spec term_to_iovec(Term, Options) -> ext_iovec() when Term :: term(), Options :: [compressed | {compressed, Level :: 0..9} | deterministic | {minor_version, Version :: 0..2} | local].
返回根据 Erlang 外部项格式编码的 Term
,作为 ext_iovec/0
。
此函数产生的编码与 term_to_binary/2
相同,但返回类型不同。调用 iolist_to_binary(term_to_iovec(Term, Opts))
将产生与 term_to_binary(Term, Opts)
完全相同的结果。
当前可识别的选项是 term_to_binary/2
可识别的所有选项。
term_to_iovec()
是对 term_to_binary()
提供的功能的纯优化。term_to_iovec()
例如可以直接引用堆外二进制文件,而不是将二进制数据复制到结果中。
另请参阅 term_to_binary/2
。
-spec tl(List) -> Tail when List :: nonempty_maybe_improper_list(), Tail :: term().
返回 List
的尾部,即列表减去第一个元素
它适用于非正常列表。
示例
> tl([geesties, guilies, beasties]).
[guilies, beasties]
> tl([geesties]).
[]
> tl([geesties, guilies, beasties | improper_end]).
[guilies, beasties | improper_end]
> tl([geesties | improper_end]).
improper_end
失败:如果 List
是空列表 []
,则返回 badarg
。
截断 Number
的小数部分。
例如
> trunc(5.7).
5
> trunc(-5.7).
-5
> trunc(5).
5
> trunc(36028797018963969.0).
36028797018963968
在最后一个示例中,trunc(36028797018963969.0)
的求值结果为 36028797018963968
。其原因是数字 36028797018963969.0
无法精确地表示为浮点值。相反,浮点字面量表示为 36028797018963968.0
,这是可以精确表示为浮点值的最接近的数字。有关更多信息,请参阅 浮点数的表示。
-spec tuple_size(Tuple) -> non_neg_integer() when Tuple :: tuple().
返回一个整数,它是 Tuple
中的元素数量。
例如
> tuple_size({morni, mulle, bwange}).
3
返回与 Tuple
对应的列表。Tuple
可以包含任何 Erlang 项。例如
> tuple_to_list({share, {'Ericsson_B', 163}}).
[share,{'Ericsson_B',163}]
-spec unique_integer() -> integer().
生成并返回一个在当前运行时系统实例上唯一的整数。等效于调用 erlang:unique_integer([])
。
-spec unique_integer(ModifierList) -> integer() when ModifierList :: [Modifier], Modifier :: positive | monotonic.
生成并返回一个在当前运行时系统实例上唯一的整数。该整数是唯一的,因为这个 BIF 使用相同的修饰符集,在当前运行时系统实例上不会多次返回相同的整数。当然,每个整数值都可以通过其他方式构造。
默认情况下,当 []
作为 ModifierList
传递时,可以返回负整数和正整数。这是为了尽可能多地使用不需要堆内存分配的整数范围。默认情况下,返回的整数也仅保证是唯一的,也就是说,任何返回的整数都可能小于或大于先前返回的整数。
Modifier
s
positive - 仅返回正整数。
请注意,通过传递
positive
修饰符,您将更快地获得堆分配的整数(大数)。monotonic - 返回与创建时间相对应的严格单调递增的整数。也就是说,返回的整数始终大于当前运行时系统实例上先前返回的整数。
这些值可以用来确定运行时系统实例上事件之间的顺序。也就是说,如果同一个运行时系统实例上的不同进程(或同一个进程)都执行了
X = erlang:unique_integer([monotonic])
和Y = erlang:unique_integer([monotonic])
,并且X < Y
,我们就知道X
是在Y
之前创建的。警告
严格单调递增的值本质上生成成本很高,并且扩展性较差。这是因为这些值需要在 CPU 核心之间同步。也就是说,除非你真的需要严格单调递增的值,否则不要传递
monotonic
修饰符。
所有有效的 Modifier
都可以组合使用。ModifierList
中重复(有效)的 Modifier
会被忽略。
注意
通过使用不同的
Modifier
集合调用erlang:unique_integer/1
返回的整数集合会重叠。例如,通过重复调用unique_integer([monotonic])
和unique_integer([positive, monotonic])
,你最终会看到一些被两个调用都返回的整数。
失败
badarg
- 如果ModifierList
不是一个正确的列表。badarg
- 如果Modifier
不是一个有效的修饰符。
进程和端口
-spec alias() -> Alias when Alias :: reference().
等效于 alias([])
。
-spec alias(Opts) -> Alias when Alias :: reference(), Opts :: [explicit_unalias | reply].
创建一个别名,该别名可在向创建该别名的进程发送消息时使用。当别名被禁用时,使用该别名发送的消息将被丢弃。可以使用 unalias/1
禁用别名。
目前可用于 alias/1
的选项
explicit_unalias
- 别名只能通过调用unalias/1
来停用。如果没有传递任何选项或调用了alias/0
,这也是默认行为。reply
- 当收到通过别名发送的回复消息时,别名将自动停用。别名仍然可以通过调用unalias/1
来停用。
示例
server() ->
receive
{request, AliasReqId, Request} ->
Result = perform_request(Request),
AliasReqId ! {reply, AliasReqId, Result}
end,
server().
client(ServerPid, Request) ->
AliasReqId = alias([reply]),
ServerPid ! {request, AliasReqId, Request},
%% Alias will be automatically deactivated if we receive a reply
%% since we used the 'reply' option...
receive
{reply, AliasReqId, Result} -> Result
after 5000 ->
unalias(AliasReqId),
%% Flush message queue in case the reply arrived
%% just before the alias was deactivated...
receive {reply, AliasReqId, Result} -> Result
after 0 -> exit(timeout)
end
end.
请注意,此示例中的服务器和客户端都必须在至少 OTP 24 系统上执行才能工作。
有关进程别名的更多信息,请参阅Erlang 参考手册的 进程别名 部分。
调用一个 fun,将 Args
中的元素作为参数传递。
如果在编译时已知参数中的元素数量,则最好将调用写为 Fun(Arg1, Arg2, ... ArgN)
。
警告
之前,
Fun
也可以指定为{Module, Function}
,等效于apply(Module, Function, Args)
。这种用法已弃用,将在未来的版本中停止工作。
-spec apply(Module, Function, Args) -> term() when Module :: module(), Function :: atom(), Args :: [term()].
返回将 Module
中的 Function
应用于 Args
的结果。应用的函数必须从 Module
导出。函数的arity 是 Args
的长度。
例如
> apply(lists, reverse, [[a, b, c]]).
[c,b,a]
> apply(erlang, atom_to_list, ['Erlang']).
"Erlang"
如果在编译时已知参数的数量,则最好将调用写为 Module:Function(Arg1, Arg2, ..., ArgN)
。
失败:如果应用的函数未导出,则会调用 error_handler:undefined_function/3
。错误处理程序可以重新定义(请参阅 process_flag/2
)。如果 error_handler
未定义,或者用户已重新定义了默认的 error_handler
,导致替换模块未定义,则会生成一个带有原因 undef
的错误。
-spec bump_reductions(Reductions) -> true when Reductions :: pos_integer().
这个依赖于实现的函数会增加调用进程的规约计数器。
在 Beam 模拟器中,通常每个函数和 BIF 调用都会使归约计数器加一。当计数器达到进程的最大归约次数(Erlang/OTP 19.2 及更高版本中为 4000 次归约)时,会强制进行上下文切换。
警告
此 BIF 可能会在 Beam 机器的未来版本中删除,恕不另行通知。它不太可能在其他 Erlang 实现中实现。
-spec demonitor(MonitorRef) -> true when MonitorRef :: reference().
如果 MonitorRef
是调用进程通过调用 monitor/2
获取的引用,则此监视将关闭。如果监视已关闭,则不会发生任何操作。
一旦 demonitor(MonitorRef)
返回,保证将来不会因为监视器而将 {'DOWN', MonitorRef, _, _, _}
消息放入调用者的消息队列中。但是,调用之前可能已经在调用者的消息队列中放入了 {'DOWN', MonitorRef, _, _, _}
消息。因此,通常建议在停止监视后从消息队列中删除此类 'DOWN'
消息。如果需要此清理,可以使用 demonitor(MonitorRef, [flush])
代替 demonitor(MonitorRef)
。
注意
有关分布式信号的一些重要信息,请参阅Erlang 参考手册的进程章节中的 分布式阻塞信号 部分。
变更
在 Erlang/OTP R11B (ERTS 5.5) 之前,
demonitor/1
的行为是完全异步的,也就是说,监视器在“取消监视信号”到达被监视实体之前一直处于活动状态。这有一个不良影响。你永远无法知道何时保证不会收到因为监视器而产生的DOWN
消息。当前行为可以视为两个组合操作:异步发送“取消监视信号”到被监视实体,并忽略监视器的任何未来结果。
失败:如果 MonitorRef
指的是另一个进程启动的监视,则会发生错误。并非所有此类情况的检查都很便宜。如果检查成本低廉,则调用会失败并返回 badarg
,例如,如果 MonitorRef
是一个远程引用。
-spec demonitor(MonitorRef, OptionList) -> boolean() when MonitorRef :: reference(), OptionList :: [Option], Option :: flush | info.
除非 info
是 OptionList
的一部分,否则返回的值为 true
。
demonitor(MonitorRef, [])
等效于 demonitor(MonitorRef)
。
Option
s
flush
- 如果存在{_, MonitorRef, _, _, _}
消息,则在停止监视后,从调用者的消息队列中删除(一个)该消息。调用
demonitor(MonitorRef, [flush])
等效于以下操作,但效率更高demonitor(MonitorRef), receive {_, MonitorRef, _, _, _} -> true after 0 -> true end
info
- 返回的值是以下之一true
- 找到并移除了监视器。在这种情况下,与此监视器对应的'DOWN'
消息尚未被传递,也不会被传递。false
- 未找到监视器,无法移除。这可能是因为有人已经将与此监视器对应的'DOWN'
消息放入了调用者的消息队列中。
如果选项
info
与选项flush
组合使用,则如果需要刷新,则返回false
,否则返回true
。
变更
在未来的版本中可以添加更多选项。
失败
badarg
- 如果OptionList
不是列表。badarg
- 如果Option
是一个无效的选项。badarg
- 与demonitor/1
相同的失败。
返回进程字典并将其删除。
例如
> put(key1, {1, 2, 3}),
put(key2, [a, b, c]),
erase().
[{key1,{1,2,3}},{key2,[a,b,c]}]
返回与 Key
关联的值 Val
,并将其从进程字典中删除。如果 Key
没有关联的值,则返回 undefined
。
此函数当前实现的平均时间复杂度为 O(1
),最坏情况下的时间复杂度为 O(N
),其中 N
是进程字典中的项目数。
例如
> put(key1, {merry, lambs, are, playing}),
X = erase(key1),
{X, erase(key1)}.
{{merry,lambs,are,playing},undefined}
引发一个带有原因 Reason
的 error
类异常。
由于求值此函数会导致抛出异常,因此它没有返回值。
异常类 error
的目的是表示发生了意外错误(例如,使用类型不正确的参数调用函数)。有关更多信息,请参阅有关 错误和错误处理 的指南。示例
> catch error(foobar).
{'EXIT',{foobar,[{shell,apply_fun,3,
[{file,"shell.erl"},{line,906}]},
{erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,677}]},
{erl_eval,expr,5,[{file,"erl_eval.erl"},{line,430}]},
{shell,exprs,7,[{file,"shell.erl"},{line,687}]},
{shell,eval_exprs,7,[{file,"shell.erl"},{line,642}]},
{shell,eval_loop,3,[{file,"shell.erl"},{line,627}]}]}}
引发一个带有原因 Reason
的 error
类异常。Args
应该为当前函数的参数列表或原子 none
。
如果 Args
是一个列表,它用于为堆栈回溯中的当前函数提供参数。如果它是 none
,则在堆栈跟踪中使用调用函数的元数。由于求值此函数会导致引发异常,因此它没有返回值。
异常类 error
的目的是表示发生了意外错误(例如,使用类型不正确的参数调用函数)。有关更多信息,请参阅有关 错误和错误处理 的指南。示例
test.erl
:
-module(test).
-export([example_fun/2]).
example_fun(A1, A2) ->
erlang:error(my_error, [A1, A2]).
Erlang shell
6> c(test).
{ok,test}
7> test:example_fun(arg1,"this is the second argument").
** exception error: my_error
in function test:example_fun/2
called as test:example_fun(arg1,"this is the second argument")
-spec error(Reason, Args, Options) -> no_return() when Reason :: term(), Args :: [term()] | none, Options :: [Option], Option :: {error_info, ErrorInfoMap}, ErrorInfoMap :: #{cause => term(), module => module(), function => atom()}.
引发一个带有原因 Reason
的 error
类异常。Args
应该为当前函数的参数列表或原子 none
。
如果 Args
是一个列表,它用于为堆栈回溯中的当前函数提供参数。如果它是 none
,则在堆栈跟踪中使用调用函数的元数。由于求值此函数会导致引发异常,因此它没有返回值。
如果给定 error_info
选项,ErrorInfoMap
将插入到堆栈跟踪中。在 ErrorInfoMap
中给出的信息将由错误格式化程序(如 erl_error
)使用,以提供有关错误的更多上下文。
ErrorInfoMap
的默认 module
是调用 error/3
的模块。默认的 function
是 format_error
。有关如何使用此 Module:Function/2 的更多详细信息,请参阅 format_error/2
异常类 error
的目的是表示发生了意外错误(例如,使用类型不正确的参数调用函数)。有关更多信息,请参阅有关 错误和错误处理 的指南。
引发一个带有退出原因 Reason
的 exit
类异常。
由于求值此函数会导致引发异常,因此它没有返回值。
异常类 exit
的目的是当前进程应该停止(例如,当收到告诉进程停止的消息时)。
此函数与 error/1,2,3
的不同之处在于,它会导致不同类的异常,并且具有不包含来自调用堆栈的函数列表的原因。
有关更多信息,请参阅有关 错误和错误处理 的指南。
示例
> exit(foobar).
** exception exit: foobar
> catch exit(foobar).
{'EXIT',foobar}
注意
如果一个进程调用
exit(kill)
并且没有捕获异常,它将以退出原因kill
终止,并且还会向所有链接的进程发出退出信号,退出原因也是kill
(不是killed
)。这种退出原因 为kill
的退出信号可以被链接的进程捕获。请注意,这意味着退出原因 为kill
的信号的行为取决于它们的发送方式,因为如果进程使用erlang:exit/2
向另一个进程发送这样的信号,则该信号将是不可捕获的。
将带有退出原因 Reason
的退出信号发送到由 Pid
标识的进程或端口。
如果 Reason
是除 normal
或 kill
之外的任何项,并且 P
是由 Pid
标识的进程或端口,则适用以下行为:
- 如果
P
没有 捕获退出信号,则P
将以退出原因Reason
退出。 - 如果
P
有 捕获退出信号,则退出信号将转换为消息{'EXIT', From, Reason}
,其中From
是发送退出信号的进程的进程标识符,并传递到P
的消息队列。
如果 Reason
是项 normal
并且 Pid
是进程 P
的标识符,而 P
与调用 erlang:exit(Pid, normal)
的进程不同(当进程向自身发送 normal
原因的信号时的行为在警告中描述),则适用以下行为:
- 如果
P
有 捕获退出信号,则退出信号将转换为消息{'EXIT', From, normal}
,其中From
是发送退出信号的进程的进程标识符,并传递到P
的消息队列。 - 如果
P
没有捕获退出信号,则该信号无效。
如果 Reason
是原子 kill
,即如果调用了 exit(Pid, kill)
,则会向由 Pid
标识的进程发送一个不可捕获的退出信号,该进程将无条件地以退出原因 killed
退出。退出原因从 kill
更改为 killed
,以提示链接的进程被终止的进程是通过调用 exit(Pid, kill)
终止的。
注意
函数
erlang:exit/1
和erlang:exit/2
名称相似,但提供非常不同的功能。erlang:exit/1
函数应在旨在停止当前进程时使用,而erlang:exit/2
应在旨在向另一个进程发送退出信号时使用。另请注意,erlang:exit/1
会引发可捕获的异常,而erlang:exit/2
不会导致引发任何异常。
警告
上述描述中未涵盖的唯一情况是当进程
P
向自身发送退出原因 为normal
的退出信号时,即erlang:exit(self(), normal)
。在这种情况下,行为如下:
- 如果
P
有 捕获退出信号,则退出信号将转换为消息{'EXIT', From, normal}
,其中From
是P
的进程标识符,并传递到P
的消息队列。- 如果
P
没有捕获退出信号,则P
将以原因normal
退出。请注意,上述行为与进程向另一个进程发送退出原因 为
normal
的退出信号时的行为不同。这可以说很奇怪,但为了向后兼容性而保留了这种行为。
注意
有关分布式信号的一些重要信息,请参阅Erlang 参考手册的进程章节中的 分布式阻塞信号 部分。
-spec garbage_collect() -> true.
强制立即对正在执行的进程进行垃圾回收。
除非已注意到(或有充分理由怀疑)自发垃圾回收会发生得太晚或根本不会发生,否则不应使用该函数。
警告
不当使用会严重降低系统性能。
-spec garbage_collect(Pid, OptionList) -> GCResult | async when Pid :: pid(), RequestId :: term(), Option :: {async, RequestId} | {type, major | minor}, OptionList :: [Option], GCResult :: boolean().
垃圾回收由 Pid
标识的节点本地进程。
选项
:
{async, RequestId}
- 函数garbage_collect/2
在发送请求后立即返回值async
。当请求被处理后,调用此函数的进程会收到一条形式为{garbage_collect, RequestId, GCResult}
的消息。{type, 'major' | 'minor'}
- 触发请求类型的垃圾回收。默认值为'major'
,这将触发完全扫描 GC。选项'minor'
被认为是一个提示,可能会导致执行次要或主要 GC。
如果 Pid
等于 self/0
,并且没有传递 async
选项,则会立即执行垃圾回收,即与调用 garbage_collect/0
相同。否则,会向由 Pid
标识的进程发送垃圾回收请求,并在适当的时候进行处理。如果没有传递 async
选项,则调用方会阻塞,直到 GCResult
可用并可以返回。
GCResult
告知垃圾回收请求的结果如下:
true
- 由Pid
标识的进程已进行垃圾回收。false
- 没有执行垃圾回收,因为由Pid
标识的进程在满足请求之前终止。
请注意,与 garbage_collect/0
适用相同的注意事项。
失败
badarg
- 如果Pid
不是节点本地进程标识符。badarg
- 如果OptionList
是无效的选项列表。
将进程字典作为 {Key, Val}
元组的列表返回。返回列表中的项可以按任意顺序排列。
例如
> put(key1, merry),
put(key2, lambs),
put(key3, {are, playing}),
get().
[{key1,merry},{key2,lambs},{key3,{are,playing}}]
返回进程字典中与 Key
关联的值 Val
,如果 Key
不存在,则返回 undefined
。
此函数当前实现的预期时间复杂度为 O(1
),最坏情况时间复杂度为 O(N
),其中 N
是进程字典中的项目数。
例如
> put(key1, merry),
put(key2, lambs),
put({any, [valid, term]}, {are, playing}),
get({any, [valid, term]}).
{are,playing}
-spec get_keys() -> [Key] when Key :: term().
返回进程字典中所有键的列表。返回列表中的项可以是任意顺序。
例如
> put(dog, {animal,1}),
put(cow, {animal,2}),
put(lamb, {animal,3}),
get_keys().
[dog,cow,lamb]
返回进程字典中与值 Val
关联的键的列表。返回列表中的项可以是任意顺序。
例如
> put(mary, {1, 2}),
put(had, {1, 2}),
put(a, {1, 2}),
put(little, {1, 2}),
put(dog, {1, 3}),
put(lamb, {1, 2}),
get_keys({1, 2}).
[mary,had,a,little,lamb]
-spec group_leader() -> pid().
返回正在评估该函数的进程的组长的进程标识符。
每个进程都是某个进程组的成员,并且所有组都有一个组长。该组的所有 I/O 都被引导到组长。当生成一个新进程时,它会获得与生成进程相同的组长。
最初,在系统启动时,init
既是它自己的组长,也是所有进程的组长。在系统引导期间,进程的组长将根据系统的需要进行更改。以下是一些执行此操作的示例:
- 当应用程序启动时,该应用程序的顶级主管的组长将设置为应用程序主节点。有关更多详细信息,请参阅
application:start/2
。 - 在运行测试时,
common_test
和eunit
都会设置组长,以便捕获来自测试用例的任何 I/O。 - 交互式 Shell 设置组长以拦截 I/O。
将 Pid
的组长设置为 GroupLeader
。通常,当从某个 shell 启动的进程要拥有与 init
不同的组长时会使用此方法。
在具有监管树的应用程序中,组长很少应该被更改,因为 OTP 假设其进程的组长是其应用程序主节点。
设置组长遵循Erlang 参考手册中进程章节中所述的信号排序保证。
另请参阅 group_leader/0
和与启动和停止应用程序相关的 OTP 设计原则。
注意
有关分布式信号的一些重要信息,请参阅Erlang 参考手册的进程章节中的 分布式阻塞信号 部分。
-spec hibernate(Module, Function, Args) -> no_return() when Module :: module(), Function :: atom(), Args :: [term()].
使调用进程进入等待状态,其内存分配已尽可能减少。如果进程不希望很快收到任何消息,则此方法很有用。
当向该进程发送消息时,该进程将被唤醒,并且控制权将在 Module:Function
中恢复,参数由 Args
指定,调用堆栈为空,这意味着当该函数返回时,进程终止。因此,erlang:hibernate/3
永远不会返回给其调用者。恢复函数 Module:Function/Arity
必须导出 (Arity
=:= length(Args)
)。
如果进程的消息队列中有任何消息,该进程会立即被唤醒,其方式与之前描述的相同。
更技术性地来说,erlang:hibernate/3
会丢弃进程的调用栈,然后对进程进行垃圾回收。之后,所有存活的数据都会位于一个连续的堆中。堆的大小随后会缩小到与其所保存的存活数据完全相同的大小(即使该大小小于进程的最小堆大小)。
如果进程中存活数据的大小小于最小堆大小,则进程唤醒后发生的第一次垃圾回收会确保堆大小被更改为不小于最小堆大小的值。
请注意,清空调用栈意味着任何外部的 catch
都会被移除,并且必须在休眠后重新插入。这样做的一个影响是,使用 proc_lib
启动的进程(也包括间接启动的进程,例如 gen_server
进程)应使用 proc_lib:hibernate/3
来代替,以确保在进程唤醒时异常处理程序可以继续工作。
Pid
必须引用本地节点上的进程。
如果进程存在且处于活动状态,即没有正在退出或已经退出,则返回 true
。否则返回 false
。
如果进程 P1
调用 is_process_alive(P2Pid)
,则保证从 P1
发送到 P2
(P2
是标识符为 P2Pid
的进程)的所有信号,会在检查 P2
的活跃性之前被传递到 P2
。此保证意味着可以使用 is_process_alive/1
让进程 P1
等待,直到进程 P2
(已从 P1 收到带有 kill
原因的退出信号)被杀死。
例如
exit(P2Pid, kill),
% P2 might not be killed
is_process_alive(P2Pid),
% P2 is not alive (the call above always return false)
有关信号和退出信号的更多信息,请参阅有关信号和erlang:exit/2的文档。
在调用进程和另一个由 PidOrPort
标识的进程或端口之间建立并激活链接。
从这里开始,我们将被标识的进程或端口称为被链接者。如果被链接者是端口,则它必须与调用者位于同一节点上。
如果链接的参与者之一终止,它将向另一个参与者发送退出信号。退出信号将包含终止参与者的退出原因。由于链接而触发退出信号的其他情况包括当被链接者不存在(noproc
退出原因)以及当不同节点上链接进程之间的连接丢失或无法建立时(noconnection
退出原因)。
可以通过调用 unlink/1
来删除现有链接。有关链接和由于链接引起的退出信号的更多信息,请参阅Erlang 参考手册中的进程章节
由于历史原因,当检查被链接者是否存在“廉价”且调用者未捕获退出时,link/1
具有奇怪的半同步行为。如果以上情况为真,并且被链接者不存在,则 link/1
将引发 noproc
错误异常。预期的行为应该是 link/1
返回 true
,并且调用者稍后会收到带有 noproc
退出原因的退出信号,但不幸的是事实并非如此。noproc
异常不应与带有退出原因 noproc
的退出信号混淆。目前,当被链接者应该与调用进程位于同一节点上时,检查被链接者是否存在是“廉价”的。
链接的设置和激活是异步执行的。如果链接已存在,或者如果调用者尝试创建到自身的链接,则不会执行任何操作。有关链接协议的详细描述,可以在ERTS 用户指南的分发协议章节中找到。
注意
有关分布式信号的一些重要信息,请参阅Erlang 参考手册的进程章节中的 分布式阻塞信号 部分。
失败
- 如果
PidOrPort
未标识进程或节点本地端口,则为badarg
。 noproc
被链接者不存在,并且如上所述检查它是否存在是“廉价”的。
-spec monitor(process, monitor_process_identifier()) -> MonitorRef when MonitorRef :: reference(); (port, monitor_port_identifier()) -> MonitorRef when MonitorRef :: reference(); (time_offset, clock_service) -> MonitorRef when MonitorRef :: reference().
向由 Item
标识的实体发送类型为 Type
的监视请求。
如果被监视的实体不存在或其监视状态发生变化,则 monitor/2
的调用者将收到以下格式的消息通知
{Tag, MonitorRef, Type, Object, Info}
注意
监视器请求是一个异步信号。也就是说,信号需要一段时间才能到达目的地。
Type
可以是以下原子之一:process
、port
或 time_offset
。
process
或 port
监视器仅触发一次,之后会从监视进程和被监视实体中删除。当被监视的进程或端口终止、在创建时不存在或与其的连接丢失时,会触发监视器。如果与其的连接丢失,我们不知道它是否仍然存在。当调用 demonitor/1
时,也会关闭监视。
按名称进行的 process
或 port
监视器仅在监视器实例化时将 RegisteredName
解析为 pid/0
或 port/0
,之后对名称注册的更改将不会影响现有监视器。
当触发 process
或 port
监视器时,会发送一个具有以下模式的 'DOWN'
消息
{'DOWN', MonitorRef, Type, Object, Info}
在监视器消息中,MonitorRef
和 Type
与之前描述的相同,并且
Object
- 触发事件的被监视实体。当监视进程或本地端口时,Object
将等于正在被监视的pid/0
或port/0
。当按名称监视进程或端口时,Object
将具有格式{RegisteredName, Node}
,其中RegisteredName
是与monitor/2
调用一起使用的名称,并且Node
是本地或远程节点名称(对于按名称监视的端口,Node
始终是本地节点名称)。Info
- 进程的退出原因,noproc
(进程或端口在监视器创建时不存在),或noconnection
(与被监视进程所在的节点没有连接)。监视
进程
- 在当前进程和另一个由Item
标识的进程之间创建监视器,Item
可以是pid/0
(本地或远程)、原子RegisteredName
或位于其他位置的已注册进程的元组{RegisteredName, Node}
。变更
在 ERTS 10.0 (OTP 21.0) 之前,如果被监视进程位于原始节点(例如 erl_interface 或 jinterface)上,则监视进程可能会因
badarg
而失败,在这些节点上未实现远程进程监视。现在,对此
monitor
的调用会成功,并且会创建监视器。但是,监视器只会监视连接。也就是说,{'DOWN', _, process, _, noconnection}
是唯一可能收到的消息,因为原始节点无法报告被监视进程的状态。监视
端口
- 在当前进程和由Item
标识的端口之间创建监视器,Item
可以是port/0
(仅限本地)、原子RegisteredName
或位于此节点上的已注册端口的元组{RegisteredName, Node}
。请注意,尝试监视远程端口将导致badarg
。自 OTP 19.0 起可用。
监视
time_offset
- 监视time_offset/0
在 Erlang 单调时间和 Erlang 系统时间 之间的变化。与time_offset Type
结合使用时,存在一个有效的Item
,即原子clock_service
。请注意,原子clock_service
不是进程的注册名称。在这种情况下,它用作当前运行时系统实例中运行时系统内部时钟服务的标识符。当时间偏移量发生变化时,会触发监视器。这可能是时间偏移值发生更改,也可能是当使用单次时间扭曲模式时,在时间偏移的最终确定期间,偏移从初步变为最终。当从初步时间偏移变为最终时间偏移时,无论时间偏移值是否更改,监视器都会触发一次。
如果运行时系统处于多次时间扭曲模式,则当运行时系统检测到 OS 系统时间发生变化时,时间偏移量会发生变化。但是,运行时系统不会在发生这种情况时立即检测到它。一个检查时间偏移量的任务计划至少每分钟执行一次,因此在正常运行情况下,这应该在一分钟内被检测到,但在负载较重的情况下,可能需要更长的时间。
监视器在触发后不会自动删除。也就是说,时间偏移量的重复更改会重复触发监视器。
当触发监视器时,会向监视进程发送一个
'CHANGE'
消息。'CHANGE'
消息具有以下模式{'CHANGE', MonitorRef, Type, Item, NewTimeOffset}
其中
MonitorRef
、Type
和Item
与上述描述相同,并且NewTimeOffset
是新的时间偏移量。当收到
'CHANGE'
消息时,可以保证在调用erlang:time_offset/0
时不会检索到旧的时间偏移量。请注意,在收到'CHANGE'
消息之前,您可以通过调用erlang:time_offset/0
观察到时间偏移量的变化。自 OTP 18.0 起可用。
对同一个 Item
和/或 Type
多次调用 monitor/2
不是错误;它会产生多个独立的监控实例。
监控功能预计会扩展。也就是说,预计在未来的版本中会支持其他 Type
和 Item
。
注意
如果或当
monitor/2
被扩展时,监控消息中的Tag
、Object
和Info
将会引入其他可能的值。
注意
有关分布式信号的一些重要信息,请参阅Erlang 参考手册的进程章节中的 分布式阻塞信号 部分。
-spec monitor(process, monitor_process_identifier(), [monitor_option()]) -> MonitorRef when MonitorRef :: reference(); (port, monitor_port_identifier(), [monitor_option()]) -> MonitorRef when MonitorRef :: reference(); (time_offset, clock_service, [monitor_option()]) -> MonitorRef when MonitorRef :: reference().
提供一个选项列表,用于修改由 monitor/2
提供的监视功能。Type
和 Item
参数的含义与传递给 monitor/2
时相同。
当前可用的选项
{alias, UnaliasOpt}
- 返回的监控引用也将成为调用进程的别名。也就是说,返回的引用可以用于向调用进程发送消息。另请参阅alias/0
。UnaliasOpt
确定如何停用别名。explicit_unalias
- 只有显式调用unalias/1
才会停用别名。demonitor
- 当监视器被移除时,别名将自动停用。这可以通过显式调用demonitor/1
或在由于监视器传递'DOWN'
消息时自动移除来完成。别名仍然可以通过调用unalias/1
来停用。reply_demonitor
- 当监视器被移除(请参阅上面的demonitor
选项)或通过别名发送的回复消息被接收时,别名将自动停用。当通过别名接收到回复消息时,监视器也将被自动移除。这在客户端/服务器场景中很有用,当客户端监视服务器并通过别名获取回复时。一旦收到响应,无论响应是回复还是'DOWN'
消息,别名和监视器都将被自动移除。别名仍然可以通过调用unalias/1
来停用。请注意,如果使用unalias/1
BIF 移除别名,则监视器仍将保持活动状态。
示例
server() -> receive {request, AliasReqId, Request} -> Result = perform_request(Request), AliasReqId ! {reply, AliasReqId, Result} end, server(). client(ServerPid, Request) -> AliasMonReqId = monitor(process, ServerPid, [{alias, reply_demonitor}]), ServerPid ! {request, AliasMonReqId, Request}, %% Alias as well as monitor will be automatically deactivated if we %% receive a reply or a 'DOWN' message since we used 'reply_demonitor' %% as unalias option... receive {reply, AliasMonReqId, Result} -> Result; {'DOWN', AliasMonReqId, process, ServerPid, ExitReason} -> error(ExitReason) end.
请注意,此示例中的服务器和客户端都必须在至少 OTP 24 系统上执行才能工作。
有关进程别名的更多信息,请参阅Erlang 参考手册的 进程别名 部分。
{tag, UserDefinedTag}
- 在触发监视器时传递的 监视器消息 中,将默认的Tag
替换为UserDefinedTag
。例如,当监视一个进程时,down 消息中的'DOWN'
标签将被UserDefinedTag
替换。以下示例说明如何使用
{tag, UserDefinedTag}
选项来启用 OTP 24 中引入的新的选择性接收优化,以便在向不同的服务器发出多个请求时使用server() -> receive {request, From, ReqId, Request} -> Result = perform_request(Request), From ! {reply, self(), ReqId, Result} end, server(). client(ServerPids, Request) when is_list(ServerPids) -> ReqId = make_ref(), lists:foreach(fun (ServerPid) -> _ = monitor(process, ServerPid, [{tag, {'DOWN', ReqId}}]), ServerPid ! {request, self(), ReqId, Request} end, ServerPids), receive_replies(ReqId, length(ServerPids), []). receive_replies(_ReqId, 0, Acc) -> Acc; receive_replies(ReqId, N, Acc) -> %% The compiler will detect that we match on the 'ReqId' %% reference in all clauses, and will enable the selective %% receive optimization which makes the receive able to %% skip past all messages present in the message queue at %% the time when the 'ReqId' reference was created... Res = receive {reply, ServerPid, ReqId, Result} -> %% Here we typically would have deactivated the %% monitor by a call to demonitor(Mon, [flush]) but %% we ignore this in this example for simplicity... {ok, ServerPid, Result}; {{'DOWN', ReqId}, _Mon, process, ServerPid, ExitReason} -> {error, ServerPid, ExitReason} end, receive_replies(ReqId, N-1, [Res | Acc]).
为了使此示例按预期工作,客户端必须至少在 OTP 24 系统上执行,但服务器可以在较旧的系统上执行。
其工作方式与 error/1
完全相同,但 Dialyzer 认为此 BIF 将返回任意项。当在 NIF 的存根函数中使用,以便在未加载 NIF 库时生成异常时,Dialyzer 不会生成错误警告。
其工作方式与 error/2
完全相同,但 Dialyzer 认为此 BIF 将返回任意项。当在 NIF 的存根函数中使用,以便在未加载 NIF 库时生成异常时,Dialyzer 不会生成错误警告。
-spec open_port(PortName, PortSettings) -> port() when PortName :: {spawn, Command :: string() | binary()} | {spawn_driver, Command :: string() | binary()} | {spawn_executable, FileName :: file:name_all()} | {fd, In :: non_neg_integer(), Out :: non_neg_integer()}, PortSettings :: [Opt], Opt :: {packet, N :: 1 | 2 | 4} | stream | {line, L :: non_neg_integer()} | {cd, Dir :: string() | binary()} | {env, Env :: [{Name :: os:env_var_name(), Val :: os:env_var_value() | [] | false}]} | {args, [string() | binary()]} | {arg0, string() | binary()} | exit_status | use_stdio | nouse_stdio | stderr_to_stdout | in | out | binary | eof | {parallelism, Boolean :: boolean()} | hide | {busy_limits_port, {non_neg_integer(), non_neg_integer()} | disabled} | {busy_limits_msgq, {non_neg_integer(), non_neg_integer()} | disabled}.
返回一个端口标识符,作为打开新 Erlang 端口的结果。端口可以被视为外部 Erlang 进程。
如果在 Unicode 文件名模式下运行系统,则可执行文件的名称以及在 cd
、env
、args
和 arg0
中指定的参数都将进行 Unicode 文件名转换。要避免转换或强制使用(例如 UTF-8),请以正确的编码形式提供可执行文件和/或参数作为二进制文件。有关详细信息,请参阅模块 file
、Kernel 中的函数 file:native_name_encoding/0
以及 Erlang 中使用 Unicode
用户指南。
注意
如果 Erlang 虚拟机在 Unicode 文件名转换模式下启动,则名称中的字符(如果指定为列表)只能 > 255。否则,可执行文件的名称限制为 ISO Latin-1 字符集。
PortName
s
{spawn, Command}
- 启动一个外部程序。Command
是要运行的外部程序的名称。Command
在 Erlang 工作空间之外运行,除非找到名为Command
的 Erlang 驱动程序。如果找到,则启动该驱动程序。驱动程序在 Erlang 工作空间中运行,这意味着它与 Erlang 运行时系统链接。对于外部程序,将搜索
PATH
(或使用等效方法查找程序,具体取决于操作系统)。这是通过在某些平台上调用 shell 来完成的。命令的第一个以空格分隔的标记被视为可执行文件(或驱动程序)的名称。这(以及其他因素)使得此选项不适合运行文件名或目录名中包含空格的程序。如果需要可执行文件名中包含空格,请改用{spawn_executable, Command}
。警告
在 Unix 系统上,参数作为字符串数组传递给新的操作系统进程,但在 Windows 上,由子进程解析它们,并且一些 Windows 程序可能会应用自己的规则,这些规则与标准 C 运行时
argv
解析不一致。当调用
.bat
、.cmd
或.com
文件时,这尤其麻烦,因为这些文件是通过cmd.exe
隐式运行的,后者的参数解析容易受到恶意输入的影响,并可用于运行任意 shell 命令。因此,如果您在 Windows 上运行并且执行批处理文件或
.com
应用程序,则不得将不受信任的输入作为参数传递给程序。这会影响spawn
和spawn_executable
。{spawn_executable, FileName}
- 其工作方式类似于{spawn, FileName}
,但仅运行外部可执行文件。FileName
整体用作可执行文件的名称,包括任何空格。如果要传递参数,可以使用PortSettings
args
和arg0
。通常不调用 shell 来启动程序,而是直接执行。不搜索
PATH
(或等效项)。要在PATH
中查找要执行的程序,请使用os:find_executable/1
。只有执行 shell 脚本或
.bat
文件时,才会隐式调用相应的命令解释器,但仍然没有命令参数扩展或隐式PATH
搜索。如果无法运行
FileName
,则会引发错误异常,并将 POSIX 错误代码作为原因。错误原因可能因操作系统而异。通常,当尝试运行找不到的程序时会引发错误enoent
,当指定的文件不可执行时会引发错误eacces
。{spawn_driver, Command}
- 其工作方式类似于{spawn, Command}
,但要求命令的第一个(以空格分隔的)标记是已加载的驱动程序的名称。如果未加载具有该名称的驱动程序,则会引发badarg
错误。{fd, In, Out}
- 允许 Erlang 进程访问 Erlang 当前使用的任何已打开的文件描述符。文件描述符In
可用于标准输入,文件描述符Out
可用于标准输出。它仅用于 Erlang OS 中的各种服务器(shell
和user
)。因此,它的使用是有限的。
PortSettings
是端口的设置列表。有效的设置如下
{packet, N}
- 消息前面是它们的长度,以N
个字节发送,最重要的字节优先。N
的有效值是 1、2 和 4。stream
- 输出消息在不带数据包长度的情况下发送。必须在 Erlang 进程和外部对象之间使用用户定义的协议。{line, L}
- 消息以每行的方式传递。每行(由操作系统相关的新行序列分隔)在单个消息中传递。消息数据格式为{Flag, Line}
,其中Flag
是eol
或noeol
,Line
是传递的数据(不包含新行序列)。L
指定最大行长度(以字节为单位)。长于此长度的行将以多个消息传递,除了最后一个消息之外,所有消息的Flag
都设置为noeol
。如果在除紧随新行序列之外的其他任何位置遇到文件结尾,则最后一行也会传递,并且Flag
设置为noeol
。否则,行将传递,并且Flag
设置为eol
。{packet, N}
和{line, L}
设置是互斥的。{cd, Dir}
- 仅对{spawn, Command}
和{spawn_executable, FileName}
有效。外部程序启动时,使用Dir
作为其工作目录。Dir
必须是字符串。{env, Env}
- 仅对{spawn, Command}
和{spawn_executable, FileName}
有效。启动进程的环境会使用Env
中的环境规范进行扩展。Env
必须是一个元组列表{Name, Val}
,其中Name
是一个os:env_var_name/0
,表示环境变量的名称,Val
是一个os:env_var_name/0
,表示该环境变量在生成的端口进程中的值。Name
和Val
都必须是字符串。如果
Val
设置为原子false
或空字符串(即""
或[]
),则 open_port 将认为这些变量未设置,就像调用了os:unsetenv/1
一样。有关编码要求的信息,请参阅
Name
和Val
类型的文档。{args, [ string() | binary() ]}
- 仅对{spawn_executable, FileName}
有效,并指定可执行文件的参数。每个参数都指定为一个单独的字符串,并且(在 Unix 上)最终会成为参数向量中的一个元素。在其他平台上,会模拟类似的行为。在将参数提供给可执行文件之前,shell 不会展开这些参数。最值得注意的是,这意味着不会发生文件通配符扩展。要展开参数的通配符,请使用
filelib:wildcard/1
。请注意,即使程序是 Unix shell 脚本,这意味着最终会调用 shell,也不会发生通配符扩展,并且脚本会接收到未修改的参数。在 Windows 上,通配符扩展始终取决于程序本身,因此这不是问题。可执行文件名(也称为
argv[0]
)不应在此列表中指定。正确的可执行文件名会自动用作argv[0]
,如果适用的话。如果显式要在参数向量中设置程序名称,则可以使用选项
arg0
。{arg0, string() | binary()}
- 仅对{spawn_executable, FileName}
有效,并在运行可执行文件时显式指定程序名称参数。在某些情况下,在某些操作系统上,这可能是可取的。程序对此的响应高度依赖于系统,并且不保证有特定的效果。exit_status
- 仅对{spawn, Command}
有效,其中Command
指的是外部程序,并且对{spawn_executable, FileName}
有效。当连接到端口的外部进程退出时,会向连接的进程发送一个
{Port,{exit_status,Status}}
形式的消息,其中Status
是外部进程的退出状态。如果程序在 Unix 上中止,则使用与 shell 相同的约定(即 128+signal)。如果也指定了选项
eof
,则消息eof
和exit_status
会以未指定的顺序出现。use_stdio
- 仅对{spawn, Command}
和{spawn_executable, FileName}
有效。它允许将生成的(Unix)进程的标准输入和输出(文件描述符 0 和 1)用于与 Erlang 通信。nouse_stdio
- 与use_stdio
相反。它使用文件描述符 3 和 4 与 Erlang 通信。stderr_to_stdout
- 影响到外部程序的端口。执行的程序的标准错误文件被重定向到其标准输出文件。stderr_to_stdout
和nouse_stdio
是互斥的。overlapped_io
- 仅影响 Windows 上到外部程序的端口。如果提供了此选项,则端口程序的标准输入和标准输出句柄会使用标志FILE_FLAG_OVERLAPPED
打开,以便端口程序可以在其标准句柄上执行重叠 I/O。对于简单的端口程序通常不是这种情况,但对于有经验的 Windows 程序员来说,这是一个有价值的选项。在所有其他平台上,此选项会被静默丢弃。in
- 该端口只能用于输入。out
- 该端口只能用于输出。binary
- 来自端口的所有 I/O 都是二进制数据对象,而不是字节列表。eof
- 端口不会在文件末尾关闭,也不会产生退出信号。相反,它会保持打开状态,并将{Port, eof}
消息发送到持有该端口的进程。hide
- 在 Windows 上运行时,在生成端口程序时会抑制创建新的控制台窗口。(此选项在其他平台上无效。){parallelism, Boolean}
- 设置端口并行性的调度程序提示。如果设置为true
,则虚拟机调度端口任务;这样做时,可以提高系统中的并行性。如果设置为false
,则虚拟机尝试立即执行端口任务,从而提高延迟,但会牺牲并行性。默认值可以在系统启动时通过将命令行参数+spp
传递给 erl 来设置。{busy_limits_port, {Low, High} | disabled}
- 设置用于控制端口忙碌状态的限制。当端口的内部输出队列大小大于或等于
High
字节时,它会进入忙碌状态。当它小于Low
字节时,它会离开忙碌状态。当端口处于忙碌状态时,向其发送命令的进程将被挂起,直到端口离开忙碌状态。在此上下文中,命令为Port ! {Owner, {command, Data}}
或port_command/[2,3]
。如果
Low
设置为大于High
,则Low
限制会自动调整为与High
相同。Low
和High
的有效值范围是[1, (1 bsl (8*erlang:system_info(wordsize)))-2]
。如果传递了原子disabled
,则端口永远不会进入忙碌状态。默认值为
Low = 4096
和High = 8192
。注意,此选项仅在通过打开 spawn 驱动程序和打开
fd
驱动程序来生成可执行文件(端口程序)时有效。当打开其他驱动程序时,此选项会导致失败并出现badarg
异常。{busy_limits_msgq, {Low, High} | disabled}
- 设置用于控制端口消息队列忙碌状态的限制。当端口的消息队列大小大于或等于
High
字节时,它会进入忙碌状态。当它小于Low
字节时,它会离开忙碌状态。当端口的消息队列处于忙碌状态时,向其发送命令的进程将被挂起,直到端口消息队列离开忙碌状态。在此上下文中,命令为Port ! {Owner, {command, Data}}
或port_command/[2,3]
。如果
Low
设置为大于High
,则Low
限制会自动调整为与High
相同。Low
和High
的有效值范围是[1, (1 bsl (8*erlang:system_info(wordsize)))-2]
。如果传递了原子disabled
,则端口消息队列永远不会进入忙碌状态。注意,如果驱动程序静态禁用了此功能,则除非此选项也设置为
disable
或根本未传递,否则将引发badarg
异常。默认值为
Low = 4096
和High = 8192
,除非驱动程序本身修改了这些值。注意,如果驱动程序本身也调整了这些限制并且您禁用了此功能,则驱动程序可能会失败。
spawn 驱动程序(在生成可执行文件时使用)和
fd
驱动程序不会禁用此功能,也不会自行调整这些限制。有关更多信息,请参阅文档
erl_drv_busy_msgq_limits()
。
所有端口类型的默认值为 stream
,而生成端口的默认值为 use_stdio
。
失败:如果无法打开端口,则退出原因是 badarg
、system_limit
或最能描述错误的 POSIX 错误代码,或者如果没有合适的 POSIX 代码,则为 einval
。
badarg
- 传递给open_port
的输入参数错误。system_limit
- Erlang 模拟器中所有可用的端口都在使用中。enomem
- 没有足够的内存来创建端口。eagain
- 没有更多可用的操作系统进程。enametoolong
- 外部命令太长。emfile
- 没有更多可用的文件描述符(对于运行 Erlang 模拟器的操作系统进程)。enfile
- 文件表已满(对于整个操作系统)。eacces
- 在{spawn_executable, Command}
中指定的Command
没有指向可执行文件。enoent
- 在{spawn_executable, FileName}
中指定的FileName
没有指向现有文件。
在使用使用 {spawn, Name}
、{spawn_driver, Name}
或 {spawn_executable, Name}
打开的端口期间,向其发送消息时出现的错误会使用 {'EXIT', Port, PosixCode}
形式的信号报告给所有者进程。有关 PosixCode
的可能值,请参阅 file
。
-spec port_call(Port, Operation, Data) -> term() when Port :: port() | atom(), Operation :: integer(), Data :: term().
对端口执行同步调用。Operation
和 Data
的含义取决于端口,即端口驱动程序。并非所有端口驱动程序都支持此功能。
Port
是一个端口标识符,引用一个驱动程序。
Operation
是一个整数,它被传递给驱动程序。
Data
是任何 Erlang 术语。此数据会转换为二进制术语格式并发送到端口。
返回来自驱动程序的术语。返回的数据的含义也取决于端口驱动程序。
失败
badarg
- 如果Port
不是打开端口的标识符,也不是打开端口的注册名称。如果调用进程之前已链接到由Port
标识的已关闭端口,则保证在该badarg
异常发生之前传递来自该端口的退出信号。badarg
- 如果Operation
不适合 32 位整数。badarg
- 如果端口驱动程序不支持同步控制操作。badarg
- 如果端口驱动程序出于任何原因决定如此(可能是Operation
或Data
有问题)。警告
请勿使用未知的
Port
标识符调用port_call
并期望badarg
异常。任何未定义的行为都是可能的(包括节点崩溃),具体取决于端口驱动程序如何解释提供的参数。
关闭一个打开的端口。大致与 Port ! {self(), close}
相同,只是错误行为(见下文),它是同步的,并且端口不回复 {Port, closed}
。
任何进程都可以使用 port_close/1
关闭端口,而不仅仅是端口所有者(连接的进程)。如果调用进程链接到由 Port
标识的端口,则保证在 port_close/1
返回之前传递来自端口的退出信号。
为了进行比较:只有当 Port
未引用端口或进程时,Port ! {self(), close}
才会失败并出现 badarg
。如果 Port
是一个已关闭的端口,则不会发生任何事情。如果 Port
是一个打开的端口,并且调用进程是端口所有者,则当所有缓冲区都被刷新并且端口真正关闭时,端口会回复 {Port, closed}
。如果调用进程不是端口所有者,则端口所有者会失败并出现 badsig
。
请注意,任何进程都可以使用 Port ! {PortOwner, close}
关闭端口,就好像它自己是端口所有者一样,但回复始终发送给端口所有者。
从 Erlang/OTP R16 开始,Port ! {PortOwner, close}
是真正的异步操作。请注意,此操作一直被记录为异步操作,而底层实现一直是同步的。但是,由于其错误行为,port_close/1
仍然是完全同步的。
失败:如果 Port
不是打开端口的标识符,或打开端口的注册名称,则出现 badarg
。如果调用进程之前已链接到由 Port
标识的已关闭端口,则保证在发生此 badarg
异常之前传递来自端口的退出信号。
向端口发送数据。与 Port ! {PortOwner, {command, Data}}
相同,只是错误行为并且是同步的(见下文)。
任何进程都可以使用 port_command/2
向端口发送数据,而不仅仅是端口所有者(连接的进程)。
为了进行比较:只有当 Port
未引用端口或进程时,Port ! {PortOwner, {command, Data}}
才会失败并出现 badarg
。如果 Port
是一个已关闭的端口,则数据消息会无声无息地消失。如果 Port
是打开的,并且调用进程不是端口所有者,则端口所有者会失败并出现 badsig
。如果 Data
是无效的 I/O 列表,则端口所有者也会失败并出现 badsig
。
请注意,任何进程都可以使用 Port ! {PortOwner, {command, Data}}
向端口发送数据,就好像它自己是端口所有者一样。
如果端口繁忙,则调用进程将挂起,直到端口不再繁忙为止。
从 Erlang/OTP R16 开始,Port ! {PortOwner, {command, Data}}
是真正的异步操作。请注意,此操作一直被记录为异步操作,而底层实现一直是同步的。但是,由于其错误行为,port_command/2
仍然是完全同步的。
失败
badarg
- 如果Port
不是打开端口的标识符,也不是打开端口的注册名称。如果调用进程之前已链接到由Port
标识的已关闭端口,则保证在该badarg
异常发生之前传递来自该端口的退出信号。badarg
- 如果Data
是无效的 I/O 列表。
警告
请勿向未知端口发送数据。任何未定义的行为都是可能的(包括节点崩溃),具体取决于端口驱动程序如何解释数据。
-spec port_command(Port, Data, OptionList) -> boolean() when Port :: port() | atom(), Data :: iodata(), Option :: force | nosuspend, OptionList :: [Option].
向端口发送数据。port_command(Port, Data, [])
等于 port_command(Port, Data)
。
如果端口命令中止,则返回 false
,否则返回 true
。
如果端口繁忙,则调用进程将挂起,直到端口不再繁忙为止。
Option
s
force
- 如果端口繁忙,则调用进程不会挂起,而是强制执行端口命令。如果端口的驱动程序不支持此操作,则调用将失败并出现notsup
异常。有关更多信息,请参阅驱动程序标志ERL_DRV_FLAG_SOFT_BUSY
。nosuspend
- 如果端口繁忙,则调用进程不会挂起,而是中止端口命令并返回false
。
变更
在未来的版本中可以添加更多选项。
失败
badarg
- 如果Port
不是打开端口的标识符,也不是打开端口的注册名称。如果调用进程之前已链接到由Port
标识的已关闭端口,则保证在该badarg
异常发生之前传递来自该端口的退出信号。badarg
- 如果Data
是无效的 I/O 列表。badarg
- 如果OptionList
是无效的选项列表。notsup
- 如果已传递选项force
,但端口的驱动程序不允许强制通过繁忙的端口。
警告
请勿向未知端口发送数据。任何未定义的行为都是可能的(包括节点崩溃),具体取决于端口驱动程序如何解释数据。
将端口所有者(连接的端口)设置为 Pid
。大致与 Port ! {Owner, {connect, Pid}}
相同,只是以下几点:
- 错误行为有所不同,请参见下文。
- 端口不回复
{Port,connected}
。 port_connect/1
是同步的,请参见下文。- 新的端口所有者链接到端口。
旧的端口所有者保持与端口的链接,如果不需要,则必须调用 unlink(Port)
。任何进程都可以使用 port_connect/2
将端口所有者设置为任何进程。
为了进行比较:只有当 Port
未引用端口或进程时,Port ! {self(), {connect, Pid}}
才会失败并出现 badarg
。如果 Port
是一个已关闭的端口,则不会发生任何事情。如果 Port
是一个打开的端口,并且调用进程是端口所有者,则端口会向旧的端口所有者回复 {Port, connected}
。请注意,旧的端口所有者仍链接到该端口,而新的端口所有者未链接到该端口。如果 Port
是一个打开的端口,并且调用进程不是端口所有者,则端口所有者会失败并出现 badsig
。如果 Pid
不是现有的本地进程标识符,则端口所有者也会失败并出现 badsig
。
请注意,任何进程都可以使用 Port ! {PortOwner, {connect, Pid}}
设置端口所有者,就好像它自己是端口所有者一样,但回复始终发送给端口所有者。
从 Erlang/OTP R16 开始,Port ! {PortOwner, {connect, Pid}}
是真正的异步操作。请注意,此操作一直被记录为异步操作,而底层实现一直是同步的。但是,由于其错误行为,port_connect/2
仍然是完全同步的。
失败
badarg
- 如果Port
不是打开端口的标识符,也不是打开端口的注册名称。如果调用进程之前已链接到由Port
标识的已关闭端口,则保证在该badarg
异常发生之前传递来自该端口的退出信号。badarg
- 如果由Pid
标识的进程不是现有的本地进程。
-spec port_control(Port, Operation, Data) -> iodata() | binary() when Port :: port() | atom(), Operation :: integer(), Data :: iodata().
对端口执行同步控制操作。Operation
和 Data
的含义取决于端口,即端口驱动程序。并非所有端口驱动程序都支持此控制功能。
根据端口驱动程序,返回范围为 0..255 的整数列表或二进制文件。返回数据的含义也取决于端口驱动程序。
失败
badarg
- 如果Port
不是打开的端口或打开的端口的注册名称。badarg
- 如果Operation
不适合 32 位整数。badarg
- 如果端口驱动程序不支持同步控制操作。badarg
- 如果端口驱动程序出于任何原因决定如此(可能是Operation
或Data
有问题)。警告
请勿使用未知的
Port
标识符调用port_control/3
并期望badarg
异常。任何未定义的行为都是可能的(包括节点崩溃),具体取决于端口驱动程序如何解释提供的参数。
-spec port_info(Port) -> Result when Port :: port() | atom(), ResultItem :: {registered_name, RegisteredName :: atom()} | {id, Index :: non_neg_integer()} | {connected, Pid :: pid()} | {links, Pids :: [pid()]} | {name, String :: string()} | {input, Bytes :: non_neg_integer()} | {output, Bytes :: non_neg_integer()} | {os_pid, OsPid :: non_neg_integer() | undefined}, Result :: [ResultItem] | undefined.
返回包含关于 Port
的信息的元组的列表,如果端口未打开,则返回 undefined
。
元组的顺序是未定义的,并非所有元组都是强制性的。如果端口已关闭,并且调用进程之前已链接到该端口,则保证在 port_info/1
返回 undefined
之前传递来自端口的退出信号。
结果包含有关以下 Item
的信息
registered_name
(如果端口有注册名称)id
connected
links
name
input
output
有关不同 Item
的更多信息,请参见 port_info/2
。
失败:如果 Port
不是本地端口标识符或原子,则出现 badarg
。
-spec port_info(Port, Item :: connected) -> {connected, Pid} | undefined when Port :: port() | atom(), Pid :: pid(); (Port, Item :: id) -> {id, Index} | undefined when Port :: port() | atom(), Index :: non_neg_integer(); (Port, Item :: input) -> {input, Bytes} | undefined when Port :: port() | atom(), Bytes :: non_neg_integer(); (Port, Item :: links) -> {links, Pids} | undefined when Port :: port() | atom(), Pids :: [pid()]; (Port, Item :: locking) -> {locking, Locking} | undefined when Port :: port() | atom(), Locking :: false | port_level | driver_level; (Port, Item :: memory) -> {memory, Bytes} | undefined when Port :: port() | atom(), Bytes :: non_neg_integer(); (Port, Item :: monitors) -> {monitors, Monitors} | undefined when Port :: port() | atom(), Monitors :: [{process, pid()}]; (Port, Item :: monitored_by) -> {monitored_by, MonitoredBy} | undefined when Port :: port() | atom(), MonitoredBy :: [pid()]; (Port, Item :: name) -> {name, Name} | undefined when Port :: port() | atom(), Name :: string(); (Port, Item :: os_pid) -> {os_pid, OsPid} | undefined when Port :: port() | atom(), OsPid :: non_neg_integer() | undefined; (Port, Item :: output) -> {output, Bytes} | undefined when Port :: port() | atom(), Bytes :: non_neg_integer(); (Port, Item :: parallelism) -> {parallelism, Boolean} | undefined when Port :: port() | atom(), Boolean :: boolean(); (Port, Item :: queue_size) -> {queue_size, Bytes} | undefined when Port :: port() | atom(), Bytes :: non_neg_integer(); (Port, Item :: registered_name) -> {registered_name, RegisteredName} | [] | undefined when Port :: port() | atom(), RegisteredName :: atom().
返回关于 Port
的信息。
如果由 Port
标识的端口未打开,则返回 undefined
。如果端口已关闭,并且调用进程之前已链接到该端口,则保证在 port_info/2
返回 undefined
之前传递来自端口的退出信号。
Item
是以下之一,可用于获取有关 Port
的各种信息。
connected
- 返回{connected, Pid}
,其中Pid
是连接到端口的进程的进程标识符。id
- 返回{id, Index}
,其中Index
是端口的内部索引。此索引可用于分隔端口。input
- 返回{input, Bytes}
,其中Bytes
是从端口读取的总字节数。links
- 返回{links, Pids}
,其中Pids
是端口链接到的进程的进程标识符列表。locking
- 返回{locking, Locking}
,其中Locking
是以下之一port_level
(特定于端口的锁定)driver_level
(特定于驱动程序的锁定)请注意,这些结果高度依赖于实现,并且在未来的版本中可能会更改。
自:OTP R16B
memory
- 返回{memory, Bytes}
,其中Bytes
是运行时系统为此端口分配的总字节数。端口本身可能已分配内存,但不包含在Bytes
中。自:OTP R16B
monitors
- 返回{monitors, Monitors}
,其中Monitors
表示此端口监视的进程。自:OTP R16B
monitored_by
- 返回{monitored_by, MonitoredBy}
,其中MonitoredBy
是当前正在监视给定端口的 pid 列表。自:OTP 19.0
name
- 返回{name, Name}
,其中Name
是由open_port/2
设置的命令名称。os_pid
- 返回{os_pid, OsPid}
,其中OsPid
是使用open_port({spawn | spawn_executable, Command}, Options)
创建的 OS 进程的进程标识符(或等效标识符)。如果端口不是生成 OS 进程的结果,则值为undefined
。自:OTP R16B
output
- 返回{output, Bytes}
,其中Bytes
是使用port_command/2
、port_command/3
或Port ! {Owner, {command, Data}
从 Erlang 进程写入端口的总字节数。parallelism
- 返回{parallelism, Boolean}
,其中Boolean
对应于此端口使用的端口并行提示。有关更多信息,请参阅open_port/2
的parallelism
选项。自:OTP R16B
queue_size
- 返回{queue_size, Bytes}
,其中Bytes
是端口使用 ERTS 驱动程序队列实现排队的总字节数。自:OTP R16B
registered_name
- 返回{registered_name, RegisteredName}
,其中RegisteredName
是端口的注册名称。如果端口没有注册名称,则返回[]
。
失败:如果 Port
不是本地端口标识符或原子,则出现 badarg
。
-spec ports() -> [port()].
返回与本地节点上存在的所有端口相对应的端口标识符列表。
请注意,正在退出的端口存在,但未打开。
-spec process_display(Pid, Type) -> true when Pid :: pid(), Type :: backtrace.
在 标准错误 上写入关于本地进程 Pid
的信息。
原子 Type
的唯一允许值为 backtrace
,它显示调用堆栈的内容,包括有关调用链的信息,并首先打印当前函数。输出的格式没有进一步定义。
-spec process_flag(async_dist, Boolean) -> OldBoolean when Boolean :: boolean(), OldBoolean :: boolean(); (trap_exit, Boolean) -> OldBoolean when Boolean :: boolean(), OldBoolean :: boolean(); (error_handler, Module) -> OldModule when Module :: atom(), OldModule :: atom(); (fullsweep_after, FullsweepAfter) -> OldFullsweepAfter when FullsweepAfter :: non_neg_integer(), OldFullsweepAfter :: non_neg_integer(); (min_heap_size, MinHeapSize) -> OldMinHeapSize when MinHeapSize :: non_neg_integer(), OldMinHeapSize :: non_neg_integer(); (min_bin_vheap_size, MinBinVHeapSize) -> OldMinBinVHeapSize when MinBinVHeapSize :: non_neg_integer(), OldMinBinVHeapSize :: non_neg_integer(); (max_heap_size, MaxHeapSize) -> OldMaxHeapSize when MaxHeapSize :: max_heap_size(), OldMaxHeapSize :: max_heap_size(); (message_queue_data, MQD) -> OldMQD when MQD :: message_queue_data(), OldMQD :: message_queue_data(); (priority, Level) -> OldLevel when Level :: priority_level(), OldLevel :: priority_level(); (save_calls, N) -> OldN when N :: 0..10000, OldN :: 0..10000; (sensitive, Boolean) -> OldBoolean when Boolean :: boolean(), OldBoolean :: boolean(); ({monitor_nodes, term()}, term()) -> term(); (monitor_nodes, term()) -> term().
将指示的进程标志设置为指定值。返回标志的先前值。
Flag
是以下之一
process_flag(async_dist, boolean())
为调用进程启用或禁用完全异步的分布式信号。禁用时(默认情况下),如果分发通道的缓冲区达到分发缓冲区繁忙限制,则发送分布式信号的进程将在发送操作中阻塞。该进程将保持阻塞,直到缓冲区缩小到足够的大小。在某些情况下,这可能需要相当长的时间。启用
async_dist
时,分布式信号的发送操作将始终在传出的分发通道上缓冲信号,然后立即返回。也就是说,这些发送操作永远不会阻塞发送进程。注意
由于在启用
async_dist
进程标志时,运行时系统不强制执行任何流量控制,因此您需要确保为此类数据实现流量控制,或者此类数据的数量始终是有限的。在没有流量控制的情况下启用async_dist
的无限信号通常会导致发送运行时系统在内存不足的情况下崩溃。可以通过使用
busy_dist_port
选项的erlang:system_monitor()
来监视由于禁用async_dist
而导致的阻塞。只有由(在发送信号时)禁用了async_dist
的进程缓冲的数据,才会在确定是否应阻塞调用方时进行计数。使用选项
{async_dist, Enable}
的spawn_opt()
BIF 在生成新进程时也可以在新进程上设置async_dist
标志。可以在启动运行时系统时传递命令行参数+pad <boolean>
来设置新生成进程上要使用的默认async_dist
标志。如果未传递+pad <boolean>
命令行参数,则async_dist
标志的默认值将为false
。您可以通过调用
process_info(Pid, async_dist)
来检查进程的async_dist
进程标志的状态。process_flag(trap_exit, boolean())
当
trap_exit
设置为true
时,到达进程的退出信号将转换为{'EXIT', From, Reason}
消息,这些消息可以像普通消息一样接收。如果trap_exit
设置为false
,则如果进程收到除normal
之外的退出信号,则该进程将退出,并且退出信号将传播到其链接的进程。应用程序进程通常不会捕获退出信号。另请参阅
exit/2
。process_flag(error_handler, module())
进程使用它来重新定义未定义函数调用和未定义注册进程的
error_handler
。请谨慎使用此标志,因为代码自动加载依赖于错误处理模块的正确操作。process_flag(fullsweep_after, non_neg_integer())
更改在强制调用进程进行完全扫描之前进行的最大世代垃圾回收次数。
process_flag(min_heap_size, non_neg_integer())
更改调用进程的最小堆大小。
process_flag(min_bin_vheap_size, non_neg_integer())
更改调用进程的最小二进制虚拟堆大小。
process_flag(max_heap_size, max_heap_size())
此标志设置调用进程的最大堆大小。如果
MaxHeapSize
是整数,则使用kill
和error_logger
的系统默认值。有关堆如何增长的详细信息,请参阅 ERTS 内部文档中的 调整堆大小。
size
- 进程的最大大小(以字为单位)。如果设置为零,则禁用堆大小限制。如果该值小于min_heap_size
,则会抛出badarg
。仅在触发垃圾回收时才执行大小检查。size
是触发垃圾回收时进程的整个堆。这包括所有世代堆、进程堆栈、任何 被视为堆一部分的消息,以及垃圾回收器在回收期间需要的任何额外内存。size
与使用erlang:process_info(Pid, total_heap_size)
检索到的值相同,或者通过从erlang:process_info(Pid, garbage_collection_info)
添加heap_block_size
、old_heap_block_size
和mbuf_size
得到的值相同。kill
- 当设置为true
时,如果达到最大堆大小,运行时系统会向该进程发送带有原因kill
的不可捕获退出信号。触发kill
的垃圾回收不会完成,而是进程会尽快退出。当设置为false
时,不会向进程发送退出信号,而是进程继续执行。如果未在映射中定义
kill
,则将使用系统默认值。默认系统默认值为true
。可以通过 erl 中的选项 +hmaxk 或erlang:system_flag(max_heap_size, MaxHeapSize)
来更改它。error_logger
- 当设置为true
时,运行时系统通过logger
记录错误事件,其中包含有关达到最大堆大小时的进程的详细信息。每次达到限制时,都会发送一个日志事件。如果未在映射中定义
error_logger
,则将使用系统默认值。默认系统默认值为true
。可以通过 erl 中的选项 +hmaxel 或erlang:system_flag(max_heap_size, MaxHeapSize)
来更改它。include_shared_binaries
- 当设置为true
时,堆外二进制文件会包含在与size
限制进行比较的总和中。堆外二进制文件通常是可以在进程之间共享的较大二进制文件。共享二进制文件的大小由引用它的所有进程包含。此外,即使进程仅引用了大型二进制文件的一小部分,也可能会包含该二进制文件的整个大小。如果未在映射中定义
include_shared_binaries
,则将使用系统默认值。默认系统默认值为false
。可以通过 erl 中的选项 +hmaxib 或erlang:system_flag(max_heap_size, MaxHeapSize)
来更改它。
进程的堆大小很难预测,尤其是在垃圾回收期间使用的内存量。当考虑使用此选项时,建议首先在生产环境中运行,并将
kill
设置为false
,并检查日志事件,以查看系统中进程的正常峰值大小,然后相应地调整该值。process_flag(message_queue_data, message_queue_data())
确定消息队列中的消息的存储方式,如下所示
off_heap
- 消息队列中的所有消息都将存储在进程堆之外。这意味着消息队列中的任何消息都不会成为进程垃圾回收的一部分。on_heap
- 消息队列中的所有消息最终都将放置在进程堆上。但是,它们可以临时存储在堆外。这是在 ERTS 8.0 之前消息的存储方式。
message_queue_data
进程标志的默认值由 erl 中的命令行参数+hmqd
确定。如果进程可能会在其队列中累积大量消息,建议将标志值设置为
off_heap
。这是因为堆上存储大量消息的进程的垃圾回收可能会变得非常昂贵,并且该进程会消耗大量内存。但是,当标志值为on_heap
时,实际消息传递的性能通常更好。更改标志值会导致任何现有消息被移动。移动操作已启动,但不一定在函数返回时完成。
process_flag(priority, priority_level())
设置进程优先级。
Level
是一个原子。存在四个优先级:low
、normal
、high
和max
。默认为normal
。注意
优先级
max
保留供 Erlang 运行时系统内部使用,并且不得供其他人使用。在每个优先级级别内部,进程以循环方式进行调度。
优先级为
normal
和low
的进程的执行是交错进行的。优先级为low
的进程被选择执行的频率低于优先级为normal
的进程。当存在优先级为
high
的可运行进程时,不会选择优先级为low
或normal
的任何进程执行。但是请注意,这并不意味着当进程以优先级high
运行时,没有任何优先级为low
或normal
的进程可以运行。当使用多个调度器时,可以并行运行的进程数多于优先级为high
的进程数。也就是说,优先级为low
和优先级为high
的进程可以同时执行。当存在优先级为
max
的可运行进程时,不会选择优先级为low
、normal
或high
的任何进程执行。与优先级high
一样,较低优先级的进程可以与优先级为max
的进程并行执行。调度是抢占式的。无论优先级如何,当一个进程自上次被选择执行以来已经消耗了超过一定数量的缩减时,该进程都会被抢占。
注意
不要依赖于当前的调度方式保持不变。为了更好地利用可用的处理器核心,调度方式可能会在未来的版本中更改。
没有自动机制来避免优先级反转,例如优先级继承或优先级上限。当使用优先级时,请考虑到这一点并自行处理此类情况。
从
high
优先级进程调用您无法控制的代码可能会导致high
优先级进程等待较低优先级的进程。也就是说,在调用期间有效地降低了high
优先级进程的优先级。即使在您无法控制的某个版本的代码中不是这种情况,也可能在未来的版本中发生这种情况。例如,如果high
优先级进程触发了代码加载,则可能会发生这种情况,因为代码服务器以normal
优先级运行。通常不需要
normal
以外的其他优先级。当使用其他优先级时,请谨慎使用,尤其是high
优先级。high
优先级进程只应在短时间内执行工作。在high
优先级进程中长时间繁忙循环很可能会导致问题,因为重要的 OTP 服务器以normal
优先级运行。process_flag(save_calls, 0..10000)
N
必须是 0..10000 范围内的整数。如果N
> 0,则为该进程启用调用保存。这意味着有关该进程最近的N
个全局函数调用、BIF 调用、发送和接收的信息将保存在列表中,可以使用process_info(Pid, last_calls)
检索。全局函数调用是指明确提及函数模块的调用。只保存固定数量的信息,如下所示:- 函数调用的元组
{Module, Function, Arity}
- 发送和接收的原子
send
、'receive'
和timeout
(收到消息时为'receive'
,接收超时时为timeout
)
如果
N
= 0,则禁用该进程的调用保存,这是默认设置。无论何时设置调用保存列表的大小,其内容都会被重置。- 函数调用的元组
process_flag(sensitive, boolean())
设置或清除当前进程的
sensitive
标志。当通过调用process_flag(sensitive, true)
将进程标记为敏感时,运行时系统中可用于检查进程的数据或内部工作的功能将被静默禁用。禁用的功能包括(但不限于)以下内容:
- 跟踪。仍然可以为进程设置跟踪标志,但不会生成任何类型的跟踪消息。(如果关闭
sensitive
标志,则在设置任何跟踪标志的情况下,将再次生成跟踪消息。) - 顺序跟踪。顺序跟踪令牌会照常传播,但不会生成顺序跟踪消息。
process_info/1,2
不能用于读取消息队列或进程字典(两者都返回为空列表)。无法为该进程显示堆栈回溯。
在崩溃转储中,将省略堆栈、消息和进程字典。
如果已为该进程设置
{save_calls,N}
,则不会将函数调用保存到调用保存列表中。(调用保存列表不会被清除。此外,发送、接收和超时事件仍会添加到列表中。)- 跟踪。仍然可以为进程设置跟踪标志,但不会生成任何类型的跟踪消息。(如果关闭
-spec process_flag(Pid, Flag, Value) -> OldValue when Pid :: pid(), Flag :: save_calls, Value :: non_neg_integer(), OldValue :: non_neg_integer().
以与 process_flag/2
相同的方式设置进程 Pid
的某些标志。返回标志的旧值。Flag
的有效值仅是 process_flag/2
中允许的值的子集,即 save_calls
。
失败:如果 Pid
不是本地进程,则为 badarg
。
-spec process_info(Pid) -> Info when Pid :: pid(), Info :: [InfoTuple] | undefined, InfoTuple :: process_info_result_item().
返回一个包含关于由 Pid
标识的进程的各种信息的 InfoTuple
列表,如果进程未运行,则返回 undefined
。
InfoTuple
的顺序未定义,并且并非所有 InfoTuple
都是强制性的。结果中的 InfoTuple
部分可能会在没有事先通知的情况下进行更改。
结果中包含具有以下项的 InfoTuple
:
current_function
initial_call
status
message_queue_len
links
dictionary
trap_exit
error_handler
priority
group_leader
total_heap_size
heap_size
stack_size
reductions
garbage_collection
如果由 Pid
标识的进程具有注册名称,则还会包含一个具有 registered_name
项的 InfoTuple
。
有关特定 InfoTuple
的信息,请参阅 process_info/2
。
警告
此 BIF 仅用于调试。对于所有其他用途,请使用
process_info/2
。
失败:如果 Pid
不是本地进程,则为 badarg
。
-spec process_info(Pid, Item) -> InfoTuple | [] | undefined when Pid :: pid(), Item :: process_info_item(), InfoTuple :: process_info_result_item(); (Pid, ItemList) -> InfoTupleList | [] | undefined when Pid :: pid(), ItemList :: [Item], Item :: process_info_item(), InfoTupleList :: [InfoTuple], InfoTuple :: process_info_result_item().
返回关于由 Pid
标识的进程的信息,由 Item
或 ItemList
指定。如果进程未运行,则返回 undefined
。
如果进程处于活动状态并且指定了单个 Item
,则返回的值是相应的 InfoTuple
,除非 Item =:= registered_name
且进程没有注册名称。在这种情况下,返回 []
。此奇怪的行为是出于历史原因,并且为了向后兼容而保留。
如果指定了 ItemList
,则结果为 InfoTupleList
。InfoTupleList
中的 InfoTuple
与 ItemList
中包含的相应 Item
以相同的顺序包含。有效的 Item
可以多次包含在 ItemList
中。
获取进程信息遵循 Erlang 参考手册中进程章节中描述的信号排序保证。
注意
如果
registered_name
是ItemList
的一部分,并且该进程没有注册名称,则一个{registered_name, []}
InfoTuple
*将*包含在结果InfoTupleList
中。当指定单个Item =:= registered_name
时,以及当使用process_info/1
时,此行为有所不同。
具有相应 Item
的有效 InfoTuple
{async_dist, Enabled}
- 自:OTP 25.3 起async_dist
进程标志的当前值。{backtrace, Bin}
- 二进制Bin
包含与erlang:process_display(Pid, backtrace)
输出相同的信息。使用binary_to_list/1
从二进制文件中获取字符字符串。{binary, BinInfo}
-BinInfo
是一个列表,其中包含有关此进程堆上的二进制文件的各种信息。此InfoTuple
可能会在没有事先通知的情况下进行更改或删除。在当前实现中,BinInfo
是元组列表。元组包含:BinaryId
、BinarySize
、BinaryRefcCount
。根据
message_queue_data
进程标志的值,消息队列可能会存储在堆上。{catchlevel, CatchLevel}
-CatchLevel
是此进程中当前活动捕获的数量。此InfoTuple
可能会在没有事先通知的情况下进行更改或删除。{current_function, {Module, Function, Arity} | undefined}
-Module
、Function
、Arity
是进程的当前函数调用。如果进程当前正在执行本机编译的代码,则可以返回值undefined
。{current_location, {Module, Function, Arity, Location}}
-Module
、Function
、Arity
是进程的当前函数调用。Location
是一个双元组列表,描述源代码中的位置。{current_stacktrace, Stack}
- 返回进程的当前调用堆栈回溯(堆栈跟踪)。堆栈的格式与try
的catch
部分中的格式相同。请参阅调用堆栈回溯(堆栈跟踪)。堆栈跟踪的深度根据backtrace_depth
系统标志设置进行截断。{dictionary, Dictionary}
-Dictionary
是进程字典。{{dictionary, Key}, Value}
- 与进程字典中的Key
关联的Value
。{error_handler, Module}
-Module
是进程使用的error_handler
模块(例如,用于未定义的函数调用)。{garbage_collection, GCInfo}
-GCInfo
是一个列表,其中包含有关此进程垃圾回收的各种信息。GCInfo
的内容可能会在没有事先通知的情况下进行更改。{garbage_collection_info, GCInfo}
-GCInfo
是一个列表,其中包含有关此进程垃圾回收的各种详细信息。GCInfo
的内容可能会在没有事先通知的情况下进行更改。有关每个项含义的详细信息,请参阅gc_minor_start
,位于trace:process/4
中。{group_leader, GroupLeader}
-GroupLeader
是进程 I/O 的组长。{heap_size, Size}
-Size
是进程最年轻堆代的字大小。此代包括进程堆栈。此信息高度依赖于实现,并且如果实现发生变化,则可能会更改。{initial_call, {Module, Function, Arity}}
-Module
、Function
、Arity
是启动进程的初始函数调用。{links, PidsAndPorts}
-PidsAndPorts
是进程标识符和端口标识符的列表,其中包含进程具有链接的进程或端口。{label, Label}
-Label
是进程的标签。请参阅proc_lib:get_label/1
。自:OTP 27.2 起
{last_calls, false|Calls}
- 如果未为该进程启用调用保存(请参阅process_flag/3
),则该值为false
。如果启用了调用保存,则返回一个列表,其中最后一个元素是最近调用的元素。{message_queue_len, MessageQueueLen}
-MessageQueueLen
是进程消息队列中当前消息的数量。它是作为信息项messages
返回的列表MessageQueue
的长度(见下文)。{messages, MessageQueue}
-MessageQueue
是发送给进程但尚未处理的消息列表。{min_heap_size, MinHeapSize}
-MinHeapSize
是进程的最小堆大小。{min_bin_vheap_size, MinBinVHeapSize}
-MinBinVHeapSize
是进程的最小二进制虚拟堆大小。{monitored_by, MonitoredBy}
- 监视该进程的所有进程、端口和 NIF 资源的标识符列表。{monitors, Monitors}
- 由monitor/2
启动并对该进程处于活动状态的监视器列表。对于本地进程监视器或通过进程标识符进行的远程进程监视器,该列表由以下内容组成:{process, Pid}
- 进程由进程 ID 监视。{process, {RegName, Node}}
- 本地或远程进程由名称监视。{port, PortId}
- 本地端口由端口 ID 监视。{port, {RegName, Node}}
- 本地端口由名称监视。请注意,不支持远程端口监视器,因此Node
将始终是本地节点名称。
{message_queue_data, MQD}
-MQD
是message_queue_data
进程标志的当前值,可以是off_heap
或on_heap
。有关更多信息,请参阅process_flag(message_queue_data, MQD)
的文档。{parent, Pid}
-Pid
是父进程的标识符,即生成当前进程的进程。当进程没有父进程时,将返回undefined
。只有节点上的初始进程 (init
) 缺少父进程。{priority, Level}
-Level
是进程的当前优先级级别。有关优先级的更多信息,请参阅process_flag(priority, Level)
。{reductions, Number}
-Number
是进程执行的归约次数。{registered_name, Atom}
-Atom
是注册的进程名称。如果进程没有注册名称,则此元组不会出现在列表中。{sequential_trace_token, [] | SequentialTraceToken}
-SequentialTraceToken
是进程的顺序跟踪令牌。 此InfoTuple
可能会在不事先通知的情况下更改或删除。{stack_size, Size}
-Size
是进程的堆栈大小,以字为单位。{status, Status}
-Status
是进程的状态,可以是以下之一:exiting (正在退出)
garbage_collecting (正在垃圾回收)
waiting
(等待消息)running (正在运行)
runnable
(准备运行,但另一个进程正在运行)suspended
(因“忙碌”端口或 BIFerlang:suspend_process/1,2
而暂停)
{suspending, SuspendeeList}
-SuspendeeList
是{Suspendee, ActiveSuspendCount, OutstandingSuspendCount}
元组的列表。Suspendee
是通过 BIFerlang:suspend_process/2
或erlang:suspend_process/1
被Pid
标识的进程暂停或将要暂停的进程的标识符。ActiveSuspendCount
是Suspendee
被Pid
暂停的次数。OutstandingSuspendCount
是Pid
发送的尚未完成的暂停请求的数量,即- 如果
ActiveSuspendCount =/= 0
,则Suspendee
当前处于暂停状态。 - 如果
OutstandingSuspendCount =/= 0
,则已使用erlang:suspend_process/2
的asynchronous
选项,并且被暂停者尚未被Pid
暂停。
请注意,
ActiveSuspendCount
和OutstandingSuspendCount
不是Suspendee
上的总暂停计数,仅是Pid
贡献的部分。- 如果
{total_heap_size, Size}
-Size
是进程的所有堆片段的总大小,以字为单位。这包括进程堆栈和任何被视为堆一部分的未接收消息。{trace, InternalTraceFlags}
-InternalTraceFlags
是一个整数,表示此进程的内部跟踪标志。 此InfoTuple
可能会在不事先通知的情况下更改或删除。{trap_exit, Boolean}
- 如果进程正在捕获退出,则Boolean
为true
,否则为false
。
请注意,并非所有实现都支持所有这些 Item
。
失败
badarg
- 如果Pid
不是本地进程。badarg
- 如果Item
是无效项。
-spec processes() -> [pid()].
返回与本地节点上当前存在的所有进程相对应的进程标识符列表。
请注意,正在退出的进程存在,但不是活动的。也就是说,is_process_alive/1
对正在退出的进程返回 false
,但其进程标识符是 processes/0
返回结果的一部分。
示例
> processes().
[<0.0.0>,<0.2.0>,<0.4.0>,<0.5.0>,<0.7.0>,<0.8.0>]
向进程字典添加一个新 Key
,与值 Val
关联,并返回 undefined
。如果 Key
存在,则删除旧值并将其替换为 Val
,该函数返回旧值。
此函数当前实现的平均时间复杂度为 O(1
),最坏情况下的时间复杂度为 O(N
),其中 N
是进程字典中的项目数。
例如
> X = put(name, walrus), Y = put(name, carpenter),
Z = get(name),
{X, Y, Z}.
{undefined,walrus,carpenter}
注意
如果在
catch
的作用域内计算put
时存储的值,如果在计算throw
时或发生错误时,不会撤回。
-spec raise(Class, Reason, Stacktrace) -> badarg when Class :: error | exit | throw, Reason :: term(), Stacktrace :: raise_stacktrace().
引发指定类、原因和调用堆栈回溯(stacktrace)的异常。
Class
是 error
、exit
或 throw
。因此,如果没有堆栈跟踪,erlang:raise(Class, Reason, Stacktrace)
等效于 erlang:Class(Reason)
(假设 Class
是有效类)。
Reason
可以是任何项。
Stacktrace
是 try-catch 子句中提供的列表。
try
...
catch Class:Reason:Stacktrace ->
...
end
也就是说,一个由四元组组成的列表 {Module, Function, Arity | Args, ExtraInfo}
,其中 Module
和 Function
是原子,第三个元素是整数 arity 或参数列表。堆栈跟踪还可以包含 {Fun, Args, ExtraInfo}
元组,其中 Fun
是本地 fun,Args
是参数列表。
末尾的元素 ExtraInfo
是可选的。省略它等效于指定一个空列表。
堆栈跟踪用作调用进程的异常堆栈跟踪;它被截断为当前最大堆栈跟踪深度。
由于评估此函数会导致进程终止,因此它没有返回值,除非参数无效,在这种情况下,该函数返回错误原因 badarg
。如果您想确保不返回,可以调用 error(erlang:raise(Class, Reason, Stacktrace))
并希望稍后区分异常。
有关异常类以及如何捕获异常的更多信息,请参阅有关错误和错误处理的参考手册。
使用 名称注册表
中的进程标识符 (pid) 或端口标识符注册名称 RegName
。RegName
(必须是原子)可以代替发送运算符 (RegName ! Message
) 和大多数其他将 pid 或端口标识符作为参数的 BIF 中的 pid 或端口标识符。
例如
> register(db, Pid).
true
注册名称被视为直接可见的 Erlang 资源,并在进程终止时自动注销。
失败
badarg
- 如果PidOrPort
不是现有的本地进程或端口。badarg
- 如果RegName
已在使用中。badarg
- 如果进程或端口已注册(已具有名称)。badarg
- 如果RegName
是原子undefined
。
-spec registered() -> [RegName] when RegName :: atom().
返回已使用 register/2
注册的名称列表。
例如
> registered().
[code_server, file_server, init, user, my_db]
-spec resume_process(Suspendee) -> true when Suspendee :: pid().
减少由 Suspendee
标识的进程的挂起计数。
Suspendee
之前应通过 erlang:suspend_process/2
或 erlang:suspend_process/1
被调用 erlang:resume_process(Suspendee)
的进程暂停。当 Suspendee
的暂停计数达到零时,Suspendee
将恢复,即其状态从暂停状态更改为暂停前的状态。
警告
此 BIF 仅用于调试。
失败
badarg
- 如果Suspendee
不是进程标识符。badarg
- 如果调用erlang:resume_process/1
的进程之前没有增加Suspendee
标识的进程的暂停计数。badarg
- 如果Suspendee
标识的进程不是活动的。
-spec self() -> pid().
返回调用进程的进程标识符。
例如
> self().
<0.26.0>
-spec send(Dest, Msg) -> Msg when Dest :: send_destination(), Msg :: term().
发送消息并返回 Msg
。这与使用 发送运算符 相同:Dest ! Msg
。
Dest
可以是远程或本地进程标识符、别名、(本地) 端口、本地注册名称或另一个节点上注册名称的元组 {RegName, Node}
。
如果 Dest
是原子名称,但此名称未注册,则该函数会因 badarg
运行时错误而失败。这是 send
对于无法访问的目标 Dest
(类型正确)失败的唯一情况。
注意
有关分布式信号的一些重要信息,请参阅Erlang 参考手册的进程章节中的 分布式阻塞信号 部分。
-spec send(Dest, Msg, Options) -> Res when Dest :: send_destination(), Msg :: term(), Options :: [nosuspend | noconnect], Res :: ok | nosuspend | noconnect.
要么发送消息并返回 ok
,要么不发送消息但返回其他内容(见下文)。否则与 erlang:send/2
相同。
有关更详细的说明和警告,请参阅 erlang:send_nosuspend/2,3
。
选项
nosuspend
- 如果发送方需要被挂起才能执行发送操作,则会返回nosuspend
。noconnect
- 如果目标节点需要自动连接才能执行发送操作,则会返回noconnect
。
注意
有关分布式信号的一些重要信息,请参阅Erlang 参考手册的进程章节中的 分布式阻塞信号 部分。
警告
与
erlang:send_nosuspend/2,3
类似:请谨慎使用。
-spec send_nosuspend(Dest, Msg) -> boolean() when Dest :: send_destination(), Msg :: term().
发送消息而不挂起调用者。
等效于 erlang:send(Dest, Msg, [nosuspend])
,但如果消息已发送则返回 true
,如果因为发送方需要被挂起而未发送消息则返回 false
。
此函数旨在用于向不可靠的远程节点发送操作,而不会阻塞发送(Erlang)进程。如果与远程节点(通常不是真正的 Erlang 节点,而是用 C 或 Java 编写的节点)的连接过载,此函数不会发送消息,并返回 false
。
如果 Dest
指的是繁忙的本地端口,也会发生相同的情况。对于所有其他目标(允许使用普通的发送运算符 '!'
),此函数会发送消息并返回 true
。
此函数仅在极少数情况下使用,即进程与 Erlang 节点通信,而这些节点可能会无任何痕迹地消失,导致 TCP 缓冲区和驱动程序队列在节点被 net_kernel
(由于超时)关闭之前过满。 当发生这种情况时,通常采取的正常反应是提前关闭另一个节点。
请注意,忽略此函数的返回值将导致不可靠的消息传递,这与 Erlang 编程模型相矛盾。如果此函数返回 false
,则消息不会发送。
在许多系统中,队列过载的瞬态是正常的。尽管此函数返回 false
,但这并不意味着保证另一个节点无响应,它可能只是暂时过载。此外,返回 true
仅表示消息可以在(TCP)通道上发送而不被阻塞;不能保证消息到达远程节点。对于断开连接的无响应节点,返回值是 true
(模仿运算符 !
的行为)。当函数返回 false
时,预期的行为和应采取的操作是特定于应用程序和硬件的。
警告
请谨慎使用。
-spec send_nosuspend(Dest, Msg, Options) -> boolean() when Dest :: send_destination(), Msg :: term(), Options :: [noconnect].
等效于 erlang:send(Dest, Msg, [nosuspend | Options])
,但返回布尔值。
此函数的行为类似于 erlang:send_nosuspend/2
,但采用第三个参数,即选项列表。唯一的选项是 noconnect
,如果本地节点当前无法访问远程节点,则该选项会使函数返回 false
。正常行为是尝试连接到该节点,这可能会在短时间内使进程停滞。使用选项 noconnect
可以确保在向远程进程发送消息时不会有丝毫延迟。这在与期望始终是连接方的节点(即用 C 或 Java 编写的节点)通信时特别有用。
每当函数返回 false
(无论是在发生挂起时还是在指定 noconnect
且节点尚未连接时),都保证消息未被发送。
警告
请谨慎使用。
返回通过将 Fun
应用于空列表 []
而启动的新进程的进程标识符。否则,其工作方式与 spawn/3
相同。
返回通过将 Fun
应用于 Node
上的空列表 []
而启动的新进程的进程标识符。如果 Node
不存在,则返回无用的 pid。否则,其工作方式与 spawn/3
相同。
-spec spawn(Module, Function, Args) -> pid() when Module :: module(), Function :: atom(), Args :: [term()].
返回通过将 Module:Function
应用于 Args
而启动的新进程的进程标识符。
如果 Module:Function/Arity
不存在(其中 Arity
是 Args
的长度),则新进程会评估 error_handler:undefined_function(Module, Function, Args)
。可以重新定义错误处理程序(请参阅 process_flag/2
)。如果未定义 error_handler
,或者用户已重新定义默认的 error_handler
且其替换项未定义,则会发生原因 undef
的失败。
示例
> spawn(speed, regulator, [high_speed, thin_cut]).
<0.13.1>
-spec spawn(Node, Module, Function, Args) -> pid() when Node :: node(), Module :: module(), Function :: atom(), Args :: [term()].
返回通过将 Module:Function
应用于 Node
上的 Args
而启动的新进程的进程标识符 (pid)。如果 Node
不存在,则返回无用的 pid。否则,其工作方式与 spawn/3
相同。
返回通过将 Fun
应用于空列表 []
而启动的新进程的进程标识符。在调用进程和新进程之间原子地创建链接。否则,其工作方式与 spawn/3
相同。
返回通过将 Fun
应用于 Node
上的空列表 []
而启动的新进程的进程标识符 (pid)。在调用进程和新进程之间原子地创建链接。如果 Node
不存在,则返回无用的 pid,并将原因 noconnection
的退出信号发送到调用进程。否则,其工作方式与 spawn/3
相同。
-spec spawn_link(Module, Function, Args) -> pid() when Module :: module(), Function :: atom(), Args :: [term()].
返回通过将 Module:Function
应用于 Args
而启动的新进程的进程标识符。在调用进程和新进程之间原子地创建链接。否则,其工作方式与 spawn/3
相同。
-spec spawn_link(Node, Module, Function, Args) -> pid() when Node :: node(), Module :: module(), Function :: atom(), Args :: [term()].
返回通过将 Module:Function
应用于 Node
上的 Args
而启动的新进程的进程标识符 (pid)。在调用进程和新进程之间原子地创建链接。如果 Node
不存在,则返回无用的 pid,并将原因 noconnection
的退出信号发送到调用进程。否则,其工作方式与 spawn/3
相同。
返回一个新进程的进程标识符,该进程通过将 Fun
应用于空列表 []
启动,以及为新进程创建的监视器的引用。否则,其工作方式与 spawn/3
相同。
返回一个新进程的进程标识符,该进程是通过在节点 Node
上将 Fun
应用于空列表 []
而启动的,以及为新进程创建的监视器引用。否则,其工作方式与 spawn/3
相同。
如果由 Node
标识的节点不支持分布式 spawn_monitor()
,则调用将失败,并出现 notsup
异常。
-spec spawn_monitor(Module, Function, Args) -> {pid(), reference()} when Module :: module(), Function :: atom(), Args :: [term()].
通过将 Module:Function
应用于 Args
来启动一个新进程。同时会监视该进程。返回进程标识符和监视器的引用。否则,其工作方式与 spawn/3
相同。
-spec spawn_monitor(Node, Module, Function, Args) -> {pid(), reference()} when Node :: node(), Module :: module(), Function :: atom(), Args :: [term()].
通过在节点 Node
上将 Module:Function
应用于 Args
来启动一个新进程。同时会监视该进程。返回进程标识符和监视器的引用。否则,其工作方式与 spawn/3
相同。
如果由 Node
标识的节点不支持分布式 spawn_monitor()
,则调用将失败,并出现 notsup
异常。
-spec spawn_opt(Fun, Options) -> pid() | {pid(), reference()} when Fun :: function(), Options :: [spawn_opt_option()].
返回一个新进程的进程标识符(pid),该进程是通过将 Fun
应用于空列表 []
而启动的。否则,其工作方式与 spawn_opt/4
相同。
如果指定了选项 monitor
,则会监视新创建的进程,并返回进程 id 和监视器的引用。
-spec spawn_opt(Node, Fun, Options) -> pid() | {pid(), reference()} when Node :: node(), Fun :: function(), Options :: [monitor | {monitor, [monitor_option()]} | link | OtherOption], OtherOption :: term().
返回一个新进程的进程标识符(pid),该进程是通过在 Node
上将 Fun
应用于空列表 []
而启动的。如果 Node
不存在,则返回一个无用的 pid。否则,其工作方式与 spawn_opt/4
相同。
有效的选项取决于由 Node
标识的节点支持哪些选项。有关当前 OTP 版本的本地节点的有效 Option
的描述,可以在 spawn_opt/4
的文档中找到。
-spec spawn_opt(Module, Function, Args, Options) -> Pid | {Pid, MonitorRef} when Module :: module(), Function :: atom(), Args :: [term()], Options :: [spawn_opt_option()], Pid :: pid(), MonitorRef :: reference().
与 spawn/3
的工作方式相同,只是在创建进程时指定了一个额外的选项列表。
如果指定了选项 monitor
,则会监视新创建的进程,并返回进程 id 和监视器的引用。
选项
link
- 设置与父进程的链接(如spawn_link/3
所做的那样)。monitor
- 监视新进程(如monitor(process, Pid)
所做的那样)。将返回{Pid, MonitorRef}
元组,而不是仅返回Pid
。{monitor, MonitorOpts}
- 使用选项监视新进程(如monitor(process, Pid, MonitorOpts)
所做的那样)。将返回{Pid, MonitorRef}
元组,而不是仅返回Pid
。{priority, Level}
- 设置新进程的优先级。等效于在新进程的启动函数中执行process_flag(priority, Level)
,但优先级会在进程首次被选择执行之前设置。有关优先级的更多信息,请参阅process_flag(priority, Level)
。{fullsweep_after, Number}
- 仅对性能调优有用。除非您知道执行时间或内存消耗存在问题,并且确保该选项可以改善情况,否则请勿使用此选项。Erlang 运行时系统使用分代垃圾收集方案,对至少经过一次垃圾收集的数据使用“旧堆”。当旧堆上没有更多空间时,将执行全扫描垃圾收集。
选项
fullsweep_after
可以指定强制执行全扫描之前最大分代收集次数,即使旧堆上有空间也是如此。将数字设置为零会禁用通用收集算法,也就是说,所有活动数据都会在每次垃圾收集中复制。以下是一些可能需要更改
fullsweep_after
的情况- 如果不再使用的二进制文件应尽快丢弃。(将
Number
设置为零。) - 主要包含短期数据的进程很少或从不进行全扫描,也就是说,旧堆主要包含垃圾。要确保偶尔进行全扫描,请将
Number
设置为合适的值,例如 10 或 20。 - 在 RAM 容量有限且没有虚拟内存的嵌入式系统中,您可能需要通过将
Number
设置为零来保留内存。(该值可以全局设置,请参阅erlang:system_flag/2
。)
- 如果不再使用的二进制文件应尽快丢弃。(将
{min_heap_size, Size}
- 仅对性能调优有用。除非您知道执行时间或内存消耗存在问题,并且确保该选项可以改善情况,否则请勿使用此选项。以字为单位给出最小堆大小。将此值设置得高于系统默认值可以加快某些进程的速度,因为减少了垃圾收集。但是,设置过高的值可能会浪费内存并因较差的数据局部性而减慢系统速度。因此,仅将此选项用于微调应用程序,并使用各种
Size
值来测量执行时间。{min_bin_vheap_size, VSize}
- 仅对性能调优有用。除非您知道执行时间或内存消耗存在问题,并且确保该选项可以改善情况,否则请勿使用此选项。以字为单位给出最小二进制虚拟堆大小。将此值设置得高于系统默认值可以加快某些进程的速度,因为减少了垃圾收集。但是,设置过高的值可能会浪费内存。因此,仅将此选项用于微调应用程序,并使用各种
VSize
值来测量执行时间。{max_heap_size, Size}
- 设置max_heap_size
进程标志。默认的max_heap_size
由+hmax
命令行参数在 erl 中确定。有关更多信息,请参阅process_flag(max_heap_size, Size)
的文档。{message_queue_data, MQD}
- 设置message_queue_data
进程标志的值。MQD
可以是off_heap
或on_heap
。message_queue_data
进程标志的默认值由命令行参数+hmqd
在 erl 中确定。有关更多信息,请参阅process_flag(message_queue_data, MQD)
的文档。{async_dist, Enabled}
- 自:OTP 25.3 起设置已派生进程的
async_dist
进程标志。此选项将覆盖命令行参数+pad <boolean>
设置的默认值。
-spec spawn_opt(Node, Module, Function, Args, Options) -> pid() | {pid(), reference()} when Node :: node(), Module :: module(), Function :: atom(), Args :: [term()], Options :: [monitor | {monitor, [monitor_option()]} | link | OtherOption], OtherOption :: term().
返回一个新进程的进程标识符(pid),该进程是通过在 Node
上将 Module:Function
应用于 Args
而启动的。如果 Node
不存在,则返回一个无用的 pid。否则,其工作方式与 spawn_opt/4
相同。
有效的选项取决于由 Node
标识的节点支持哪些选项。有关当前 OTP 版本的本地节点的有效 Option
的描述,可以在 spawn_opt/4
的文档中找到。
等效于调用 spawn_request(node(),Fun,[])
。也就是说,在本地节点上发起一个没有选项的 spawn 请求。
-spec spawn_request(Fun, Options) -> ReqId when Fun :: function(), Option :: {reply_tag, ReplyTag} | {reply, Reply} | spawn_opt_option(), ReplyTag :: term(), Reply :: yes | no | error_only | success_only, Options :: [Option], ReqId :: reference(); (Node, Fun) -> ReqId when Node :: node(), Fun :: function(), ReqId :: reference().
等效于 spawn_request(node(),Fun,Options)
或 spawn_request(Node,Fun,[])
,具体取决于参数。
即是以下情况之一:
- 在本地节点上的派生请求。
- 没有选项的派生请求。
-spec spawn_request(Node, Fun, Options) -> ReqId when Node :: node(), Fun :: function(), Options :: [Option], Option :: monitor | {monitor, [monitor_option()]} | link | {reply_tag, ReplyTag} | {reply, Reply} | OtherOption, ReplyTag :: term(), Reply :: yes | no | error_only | success_only, OtherOption :: term(), ReqId :: reference(); (Module, Function, Args) -> ReqId when Module :: module(), Function :: atom(), Args :: [term()], ReqId :: reference().
等效于 spawn_request(Node,erlang,apply,[Fun,[]],Options)
或 spawn_request(node(),Module,Function,Args,[])
,具体取决于参数。
即是以下情况之一:
- 使用 0 元函数
Fun
作为入口点的派生请求。 - 在本地节点上没有选项的派生请求。
如果出现以下情况,此函数将失败并抛出 badarg
异常:
Node
不是一个原子。Fun
不是一个 0 元函数。Options
不是一个正确的术语列表。
spawn_request(NodeOrModule, ModuleOrFunction, FunctionOrArgs, ArgsOrOptions)
查看源代码 (自动导入) (自 OTP 23.0 起)-spec spawn_request(Node, Module, Function, Args) -> ReqId when Node :: node(), Module :: module(), Function :: atom(), Args :: [term()], ReqId :: reference(); (Module, Function, Args, Options) -> ReqId when Module :: module(), Function :: atom(), Args :: [term()], Option :: {reply_tag, ReplyTag} | {reply, Reply} | spawn_opt_option(), ReplyTag :: term(), Reply :: yes | no | error_only | success_only, Options :: [Option], ReqId :: reference().
等效于 spawn_request(Node,Module,Function,Args,[])
或 spawn_request(node(),Module,Function,Args,Options)
,具体取决于参数。
即是以下情况之一:
- 没有选项的派生请求。
- 在本地节点上的派生请求。
-spec spawn_request(Node, Module, Function, Args, Options) -> ReqId when Node :: node(), Module :: module(), Function :: atom(), Args :: [term()], Options :: [Option], Option :: monitor | {monitor, [monitor_option()]} | link | {reply_tag, ReplyTag} | {reply, Reply} | OtherOption, ReplyTag :: term(), Reply :: yes | no | error_only | success_only, OtherOption :: term(), ReqId :: reference().
异步发送一个 spawn 请求。返回一个请求标识符 ReqId
。
如果派生操作成功,则会在由 Node
标识的节点上创建一个新进程。当派生操作成功时,默认情况下,调用者将收到一条 {ReplyTag, ReqId, ok, Pid}
形式的消息,其中 Pid
是新创建进程的进程标识符。这样的消息在文本中被称为成功消息。ReplyTag
默认是原子 spawn_reply
,除非被 {reply_tag, ReplyTag}
选项修改。新进程通过将 Module:Function
应用于 Args
来启动。
如果创建新进程失败或派生操作被连接失败中断,则派生操作失败。当派生操作失败时,默认情况下,调用者将收到一条 {ReplyTag, ReqId, error, Reason}
形式的消息,其中 Reason
是错误原因。这样的消息在文本中被称为错误消息。目前定义了以下派生错误 Reason
,但其他原因可能随时出现,恕不另行通知:
badopt
- 传递了无效的Option
作为参数。请注意,不同的运行时系统可能支持不同的选项。notsup
- 由Node
标识的节点不支持由spawn_request()
发出的派生操作。noconnection
- 无法建立与由Node
标识的节点的连接,或者在派生操作期间与该节点的连接丢失。如果连接丢失,则可能创建或未创建进程。system_limit
- 由于达到某些系统限制,无法创建新进程。通常是进程表已满。
有效的 Option
monitor
- 在没有派生操作失败的情况下,原子地为新创建的进程设置一个监视器。也就是说,好像调用进程已调用monitor(process, Pid)
,其中Pid
是新创建进程的进程标识符。spawn_request()
返回的ReqId
也用作监视器引用,好像它是从monitor(process, Pid)
返回的一样。监视器在派生操作成功之前不会为调用进程激活。在操作成功之前,监视器无法被 取消监视。对应于监视器的
'DOWN'
消息保证不会在对应于派生操作的 成功消息 之前传递。如果派生操作失败,则不会传递'DOWN'
消息。如果在派生操作期间,参与派生操作的节点之间的连接丢失,则派生操作将失败,错误原因是
noconnection
。可能创建或未创建新进程。{monitor, MonitorOpts}
- 在没有派生操作失败的情况下,原子地为新创建的进程设置一个监视器。也就是说,好像调用进程已调用monitor(process, Pid, MonitorOpts)
,其中Pid
是新创建进程的进程标识符。有关更多信息,请参阅上面的monitor
选项。请注意,监视器在派生操作成功之前不会为调用进程激活。例如,在使用监视器选项创建别名的情况下,该别名在监视器激活之前不会处于活动状态。
link
- 在没有派生操作失败的情况下,原子地在调用进程和新创建的进程之间建立链接。也就是说,好像调用进程已调用link(Pid)
,其中Pid
是新创建进程的进程标识符。链接在派生操作成功之前不会为调用进程激活。在操作成功之前,链接无法被删除。由于链接而导致的退出信号保证不会在对应于派生操作的 成功消息 之前传递。如果派生操作失败,则不会向
spawn_request()
的调用者传递由于链接而导致的退出信号。如果在派生操作期间,参与派生操作的节点之间的连接丢失,则派生操作将失败,错误原因是
noconnection
。可能创建或未创建新进程。如果已创建,则将向其传递一个退出信号,退出原因是noconnection
。{reply, Reply}
- 有效的Reply
值{reply_tag, ReplyTag}
- 将回复消息中的回复标签设置为ReplyTag
。也就是说,在由于派生操作而发送给调用者的 成功 或 错误 消息中。默认的回复标签是原子spawn_reply
。OtherOption
- 其他有效的选项取决于由Node
标识的节点支持哪些选项。有关当前 OTP 版本的本地节点的其他有效Option
的说明,可以在spawn_opt/4
的文档中找到。
如果传递了派生回复消息,则保证在将任何其他来自新派生进程的信号传递给发出派生请求的进程之前传递。
如果出现以下情况,此函数将失败并抛出 badarg
异常:
Node
不是一个原子。Module
不是一个原子。Function
不是一个原子。Args
不是一个正确的术语列表。Options
不是一个正确的术语列表。
请注意,当发送生成请求时,并非所有单个 Option
都会被检查。某些 Option
只能在接收到请求时检查。因此,无效的选项不会导致 badarg
异常,而是会导致生成操作因错误原因 badopt
而失败。
可以通过调用 spawn_request_abandon/1
来放弃生成请求。
注意
有关分布式信号的一些重要信息,请参阅Erlang 参考手册的进程章节中的 分布式阻塞信号 部分。
放弃先前发出的 spawn 请求。ReqId
对应于先前由当前进程调用 spawn_request()
返回的请求标识符。也就是说,只有发出请求的进程才能放弃该请求。
只有在生成请求完成之前,才能成功放弃生成请求。当成功放弃生成请求后,调用者不会受到生成请求本身未来直接影响。例如,它不会收到生成回复消息。但是,请求不会被撤回,因此可能会或可能不会由于该请求而创建新进程。如果在放弃生成请求后创建了新进程,则由于生成请求,不会为 spawn_request_abandon/1
的调用者设置监视器或链接。如果生成请求包含 link
选项,则当检测到生成操作成功时,由于此请求而创建的进程将从其父进程收到带有退出原因 abandoned
的退出信号。
注意
由于已放弃的生成请求而创建的进程可以像任何其他进程一样与其父进程通信。只有实际生成请求对父进程的直接影响,才会被放弃生成请求取消。
返回值
true
- 生成请求已成功放弃。false
- 没有放弃任何生成请求。ReqId
请求标识符与调用进程发出的未完成的生成请求不对应。原因要么是ReqId
对应于调用进程先前发出的生成请求。生成操作已完成,并且已将生成回复传递给调用进程,除非在请求中禁用了生成回复。ReqId
与调用进程发出的生成请求不对应。
如果 ReqId
不是引用,则此函数会失败并抛出 badarg
异常。
-spec suspend_process(Suspendee) -> true when Suspendee :: pid().
暂停由 Suspendee
标识的进程。等效于调用 erlang:suspend_process(Suspendee, [])
。
警告
此 BIF 仅用于调试。
-spec suspend_process(Suspendee, OptList) -> boolean() when Suspendee :: pid(), OptList :: [Opt], Opt :: unless_suspending | asynchronous | {asynchronous, term()}.
增加由 Suspendee
标识的进程的暂停计数,如果该进程尚未处于暂停状态,则将其置于暂停状态。在进程恢复之前,暂停的进程不会被调度执行。
一个进程可以被多个进程挂起,并且可以被单个进程挂起多次。挂起的进程只有在其挂起计数达到零时才会离开挂起状态。当调用 erlang:suspend_process(Suspendee)
的同一进程调用 erlang:resume_process(Suspendee)
时,Suspendee
的挂起计数会减少。当进程终止时,进程获取的其他进程上的所有增加的挂起计数都会自动减少。
选项 (Opt
s)
asynchronous
- 将挂起请求发送到由Suspendee
标识的进程。Suspendee
最终会挂起,除非它在挂起之前被恢复。erlang:suspend_process/2
的调用者立即返回,而不管Suspendee
是否已挂起。Suspendee
挂起的时间点无法从系统中的其他事件推断出来。只能保证Suspendee
最终会挂起(除非它被恢复)。如果未传递任何asynchronous
选项,则erlang:suspend_process/2
的调用者将被阻塞,直到Suspendee
被挂起。{asynchronous, ReplyTag}
- 将挂起请求发送到由Suspendee
标识的进程。当挂起请求被处理后,会向此函数的调用者发送回复消息。回复的形式为{ReplyTag, State}
,其中State
是以下之一exited
-Suspendee
已退出。suspended
-Suspendee
现在已挂起。not_suspended
-Suspendee
未挂起。只有当发出此请求的进程在收到回复之前调用了resume_process(Suspendee)
时,才会发生这种情况。
除了回复消息外,
{asynchronous, ReplyTag}
选项的行为与没有回复标记的asynchronous
选项完全相同。unless_suspending
- 除非调用进程已经在挂起Suspendee
,否则将挂起由Suspendee
标识的进程。如果unless_suspending
与选项asynchronous
组合使用,则除非调用进程已经在挂起Suspendee
或者已经发送了挂起请求并且正在传输中,否则将发送挂起请求。如果调用进程已经在挂起Suspendee
,或者如果与选项asynchronous
组合使用并且已经有发送请求正在传输中,则返回false
,并且Suspendee
的挂起计数保持不变。
如果由 Suspendee
标识的进程的挂起计数增加,则返回 true
,否则返回 false
。
警告
此 BIF 仅用于调试。
警告
如果进程相互挂起(直接或循环),则很容易创建死锁。在 ERTS 10.0 之前的 ERTS 版本中,运行时系统会阻止此类死锁,但出于性能原因,现在已取消此阻止。
失败
badarg
- 如果Suspendee
不是进程标识符。badarg
- 如果由Suspendee
标识的进程与调用erlang:suspend_process/2
的进程是同一进程。badarg
- 如果Suspendee
标识的进程不是活动的。badarg
- 如果由Suspendee
标识的进程位于另一个节点上。badarg
- 如果OptList
不是有效的Opt
的正确列表。system_limit
- 如果由Suspendee
标识的进程被调用进程挂起的次数超过了当前使用的内部数据结构可以表示的次数。系统限制大于 2,000,000,000 次挂起,并且永远不会更低。
引发一个类为 throw
的异常。旨在用于从函数执行非本地返回。
如果在 catch 表达式中求值,则 catch 表达式返回 Any
值。
例如
> catch throw({hello, there}).
{hello,there}
如果在 try 表达式 的 try
块中求值,则可以在 catch 块中捕获值 Any
。
例如
try
throw({my_exception, "Something happened"})
catch
throw:{my_exception, Desc} ->
io:format(standard_error, "Error: ~s~n", [Desc])
end
失败:如果没有异常处理程序捕获,则为 nocatch
。
有关更多信息,请参阅有关 错误和错误处理 的指南。
停用调用进程先前创建的别名 Alias
。
例如,可以通过 alias/0
或 monitor/3
创建别名。无论创建别名时使用什么选项,unalias/1
将始终停用别名。
如果 Alias
是当前进程的当前活动别名,则返回 true;否则,返回 false。
有关进程别名的更多信息,请参阅Erlang 参考手册的 进程别名 部分。
删除调用进程与由 Id
标识的另一个进程或端口之间的链接。
从现在开始,我们将把已识别的进程或端口称为取消链接者。
可以使用 link/1
BIF 设置链接。有关链接和由于链接导致的退出信号的更多信息,请参阅 Erlang 参考手册 中的进程章节
一旦 unlink(Id)
返回,则保证调用者和取消链接者之间的链接在未来对调用者没有影响(除非再次设置链接)。请注意,如果调用者正在 捕获退出,则由于链接,{'EXIT', Id, ExitReason}
消息可能已经在 unlink(Id)
调用完成之前被放置在调用者的消息队列中。另请注意,{'EXIT', Id, ExitReason}
消息可能是链接的结果,但也可能是取消链接者通过调用 exit/2
BIF 向调用者发送退出信号的结果。因此,在调用 unlink(Id)
之后,清除消息队列可能适合也可能不适合,如下所示,当捕获退出时
unlink(Id),
receive
{'EXIT', Id, _} ->
true
after 0 ->
true
end
链接删除是异步执行的。如果不存在此类链接,则不会执行任何操作。有关 链接协议 的详细描述,请参阅 ERTS 用户指南 的 Distribution Protocol 章节。
注意
有关分布式信号的一些重要信息,请参阅Erlang 参考手册的进程章节中的 分布式阻塞信号 部分。
失败:如果 Id
未标识进程或节点本地端口,则为 badarg
。
-spec unregister(RegName) -> true when RegName :: atom().
从名称注册表
中删除与进程标识符或端口标识符关联的注册名称
RegName
。
例如
> unregister(db).
true
请记住,在注销已注册的名称后,您仍然可以接收与该名称关联的信号,因为发送者可能在发送到该名称之前查找了该名称。
建议用户不要注销系统进程。
失败:如果 RegName
不是注册的名称,则为 badarg
。
从 名称注册表
中返回具有注册名称
RegName
的进程标识符或端口标识符。如果该名称未注册,则返回 undefined
。
例如
> whereis(db).
<0.43.0>
-spec yield() -> true.
尝试让具有相同或更高优先级的其他进程(如果有)有机会在返回之前执行。无法保证在 erlang:yield/0
的调用和返回之间有任何其他进程运行。
有关如何使当前进程休眠特定毫秒数的详细信息,请参阅 receive-after
表达式 的文档。
警告
很少或几乎不需要使用此 BIF。如果不彻底了解调度程序的工作原理而使用此 BIF,可能会导致性能下降。此函数的当前实现将当前进程放在当前调度程序队列中,优先级与当前进程相同的进程的最后。
系统
-spec halt() -> no_return().
等效于调用 halt(0, [])
。
例如
> halt().
os_prompt%
-spec halt(Status :: non_neg_integer()) -> no_return(); (Abort :: abort) -> no_return(); (CrashDumpSlogan :: string()) -> no_return().
等效于调用 halt(HaltType, [])
。
例如
> halt(17).
os_prompt% echo $?
17
os_prompt%
-spec halt(Status :: non_neg_integer(), Options :: halt_options()) -> no_return(); (Abort :: abort, Options :: halt_options()) -> no_return(); (CrashDumpSlogan :: string(), Options :: halt_options()) -> no_return().
停止运行时系统。
halt(Status :: non_neg_integer(), Options :: halt_options())
使用状态码
Status
停止运行时系统。注意
在许多平台上,操作系统仅支持状态码 0-255。过大的状态码会被截断,方法是清除高位。
目前以下选项有效
{flush, EnableFlushing}
- 如果EnableFlushing
等于true
,这也是默认行为,运行时系统将在终止前执行以下操作- 刷新所有未完成的输出。
- 发送所有 Erlang 端口退出信号并等待它们退出。
- 等待所有异步线程完成所有未完成的异步作业。
- 调用所有已安装的 NIF on halt 回调。
- 等待所有启用了延迟停止设置的正在进行的NIF 调用返回。
- 调用所有已安装的
atexit
/on_exit
回调。
如果
EnableFlushing
等于false
,则运行时系统将立即终止,而不执行上述任何操作。变更
OTP 26.0 之前的运行时系统在禁用
flush
时也会调用所有已安装的atexit
/on_exit
回调,但从 OTP 26.0 开始不再是这种情况。{flush_timeout, Timeout :: 0..2147483647 | infinity}
- 限制运行时系统终止前刷新所允许的时间。Timeout
以毫秒为单位。默认值由erl
+zhft <Timeout>
命令行标志确定。如果刷新已持续
Timeout
毫秒,则刷新操作将被中断,并且运行时系统将立即以退出代码255
终止。如果未启用刷新,则超时将对系统没有影响。另请参阅
erl
+zhft <Timeout>
命令行标志。请注意,命令行标志和flush_timeout
选项设置的最短超时将是实际生效的超时值。自:OTP 27.0
halt(Abort :: abort, Options :: halt_options())
通过中止来停止 Erlang 运行时系统,并在运行时系统执行的环境中启用了核心转储时生成核心转储。
注意
{flush, boolean()}
选项将被忽略,并且将禁用刷新。halt(CrashDumpSlogan :: string(), Options :: halt_options())
停止 Erlang 运行时系统并生成一个Erlang 崩溃转储。字符串
CrashDumpSlogan
将用作创建的 Erlang 崩溃转储中的标语。如果CrashDumpSlogan
超过 1023 个字符,则标语将被截断。注意
{flush, boolean()}
选项将被忽略,并且将禁用刷新。变更
与早期版本相比的行为变更
- 在 OTP 24.2 之前,如果
CrashDumpSlogan
超过 200 个字符,则标语会被截断。现在,如果超过 1023 个字符,它将被截断。 - 在 OTP 20.1 之前,标语中仅接受范围为 0-255 的代码点。现在,任何 Unicode 字符串都有效。
- 在 OTP 24.2 之前,如果
-spec memory() -> [{Type, Size}] when Type :: memory_type(), Size :: non_neg_integer().
返回一个列表,其中包含有关 Erlang 模拟器动态分配的内存的信息。
每个列表元素都是一个元组 {Type, Size}
。第一个元素 Type
是一个描述内存类型的原子。第二个元素 Size
是内存大小(以字节为单位)。
内存类型
total
- 当前分配的总内存量。这与processes
和system
的内存大小之和相同。processes
- 当前为 Erlang 进程分配的总内存量。processes_used
- Erlang 进程当前使用的总内存量。这是作为processes
内存呈现的内存的一部分。system
- 当前为模拟器分配的与任何 Erlang 进程没有直接关系的总内存量。作为processes
呈现的内存不包含在此内存中。instrument
可用于获取此类型内存的更详细分解。atom
- 当前为原子分配的总内存量。此内存是作为system
内存呈现的内存的一部分。atom_used
- 当前用于原子的总内存量。此内存是作为atom
内存呈现的内存的一部分。binary
- 当前为二进制文件分配的总内存量。此内存是作为system
内存呈现的内存的一部分。code
- 当前为 Erlang 代码分配的总内存量。此内存是作为system
内存呈现的内存的一部分。ets
- 当前为 ETS 表分配的总内存量。此内存是作为system
内存呈现的内存的一部分。maximum
- 自模拟器启动以来分配的最大总内存量。仅当模拟器在仪表模式下运行时才存在此元组。有关如何在仪表模式下运行模拟器的信息,请参阅
instrument
和/或erl(1)
。
注意
system
值不完整。某些要作为此值一部分的已分配内存不是。当模拟器在仪表模式下运行时,
system
值更准确,但是直接为malloc
(及其类似函数)分配的内存仍然不是system
值的一部分。对malloc
的直接调用仅从特定于操作系统的运行时库以及可能来自不使用驱动程序接口中的内存分配函数的用户实现的 Erlang 驱动程序中完成。由于
total
值是processes
和system
的总和,因此system
中的错误会传播到total
值。求和的不同内存量是非原子地收集的,这会在结果中引入错误。
不同的值彼此之间具有以下关系。以大写字母开头的值不是结果的一部分。
total = processes + system
processes = processes_used + ProcessesNotUsed
system = atom + binary + code + ets + OtherSystem
atom = atom_used + AtomNotUsed
RealTotal = processes + RealSystem
RealSystem = system + MissedSystem
可以在未来的版本中在返回的列表中添加更多元组。
注意
total
值应该是由模拟器动态分配的总内存量。共享库、模拟器本身的代码以及模拟器堆栈不应该包括在内。也就是说,total
值不应该等于映射到模拟器的所有页面的总大小。此外,由于碎片和内存区域的预留,包含动态分配内存块的内存段的大小可能比动态分配内存块的总大小大得多。
变更
从 ERTS 5.6.4 开始,
erlang:memory/0
要求启用所有erts_alloc(3)
分配器(默认行为)。
失败:如果禁用了 erts_alloc(3)
分配器,则为 notsup
。
-spec memory(Type :: memory_type()) -> non_neg_integer(); (TypeList :: [memory_type()]) -> [{memory_type(), non_neg_integer()}].
返回为类型为 Type
的内存分配的内存大小(以字节为单位)。该参数也可以指定为 memory_type/0
原子的列表,在这种情况下,返回一个相应的 {memory_type(), Size :: integer >= 0}
元组列表。
变更
从 ERTS 5.6.4 开始,
erlang:memory/1
要求启用所有erts_alloc(3)
分配器(默认行为)。
失败
badarg
- 如果Type
不是erlang:memory/0
的描述中列出的内存类型之一。badarg
- 如果将maximum
作为Type
传递,并且模拟器不是在仪表模式下运行。notsup
- 如果禁用了erts_alloc(3)
分配器。
另请参阅 erlang:memory/0
。
-spec statistics(active_tasks) -> [ActiveTasks] when ActiveTasks :: non_neg_integer(); (active_tasks_all) -> [ActiveTasks] when ActiveTasks :: non_neg_integer(); (context_switches) -> {ContextSwitches, 0} when ContextSwitches :: non_neg_integer(); (exact_reductions) -> {Total_Exact_Reductions, Exact_Reductions_Since_Last_Call} when Total_Exact_Reductions :: non_neg_integer(), Exact_Reductions_Since_Last_Call :: non_neg_integer(); (garbage_collection) -> {Number_of_GCs, Words_Reclaimed, 0} when Number_of_GCs :: non_neg_integer(), Words_Reclaimed :: non_neg_integer(); (io) -> {{input, Input}, {output, Output}} when Input :: non_neg_integer(), Output :: non_neg_integer(); (microstate_accounting) -> [MSAcc_Thread] | undefined when MSAcc_Thread :: #{type := MSAcc_Thread_Type, id := MSAcc_Thread_Id, counters := MSAcc_Counters}, MSAcc_Thread_Type :: async | aux | dirty_io_scheduler | dirty_cpu_scheduler | poll | scheduler, MSAcc_Thread_Id :: non_neg_integer(), MSAcc_Counters :: #{MSAcc_Thread_State => non_neg_integer()}, MSAcc_Thread_State :: alloc | aux | bif | busy_wait | check_io | emulator | ets | gc | gc_fullsweep | nif | other | port | send | sleep | timers; (reductions) -> {Total_Reductions, Reductions_Since_Last_Call} when Total_Reductions :: non_neg_integer(), Reductions_Since_Last_Call :: non_neg_integer(); (run_queue) -> non_neg_integer(); (run_queue_lengths) -> [RunQueueLength] when RunQueueLength :: non_neg_integer(); (run_queue_lengths_all) -> [RunQueueLength] when RunQueueLength :: non_neg_integer(); (runtime) -> {Total_Run_Time, Time_Since_Last_Call} when Total_Run_Time :: non_neg_integer(), Time_Since_Last_Call :: non_neg_integer(); (scheduler_wall_time) -> [{SchedulerId, ActiveTime, TotalTime}] | undefined when SchedulerId :: pos_integer(), ActiveTime :: non_neg_integer(), TotalTime :: non_neg_integer(); (scheduler_wall_time_all) -> [{SchedulerId, ActiveTime, TotalTime}] | undefined when SchedulerId :: pos_integer(), ActiveTime :: non_neg_integer(), TotalTime :: non_neg_integer(); (total_active_tasks) -> ActiveTasks when ActiveTasks :: non_neg_integer(); (total_active_tasks_all) -> ActiveTasks when ActiveTasks :: non_neg_integer(); (total_run_queue_lengths) -> TotalRunQueueLengths when TotalRunQueueLengths :: non_neg_integer(); (total_run_queue_lengths_all) -> TotalRunQueueLengths when TotalRunQueueLengths :: non_neg_integer(); (wall_clock) -> {Total_Wallclock_Time, Wallclock_Time_Since_Last_Call} when Total_Wallclock_Time :: non_neg_integer(), Wallclock_Time_Since_Last_Call :: non_neg_integer().
返回有关当前系统的统计信息。
可能的标志是
statistics(active_tasks) -> [non_neg_integer()]
返回与
statistics(active_tasks_all)
相同的结果,但脏 IO 运行队列及其关联的调度程序的信息不包含在结果中。也就是说,结果中只包含预期为 CPU 绑定的任务。自 OTP 18.3 起可用
statistics(active_tasks_all) -> [non_neg_integer()]
返回一个列表,其中每个元素表示每个运行队列及其关联的调度程序上活动进程和端口的数量。也就是说,准备运行或当前正在运行的进程和端口的数量。正常运行队列及其关联的调度程序的值首先位于结果列表中。第一个元素对应于调度程序编号 1,依此类推。如果存在对脏调度程序的支持,则随后会有一个具有脏 CPU 运行队列及其关联的脏 CPU 调度程序的值的元素,然后作为最后一个元素,脏 IO 运行队列及其关联的脏 IO 调度程序的值会跟随。该信息是非原子地收集的。也就是说,结果不一定是状态的一致快照,而是非常有效地收集的。
注意
每个普通调度器管理一个运行队列。如果支持脏调度器,所有脏 CPU 调度器共享一个运行队列,所有脏 IO 调度器共享一个运行队列。也就是说,我们有多个普通运行队列,一个脏 CPU 运行队列和一个脏 IO 运行队列。工作负载不能在不同类型的运行队列之间迁移。只有普通运行队列中的工作负载才能迁移到其他普通运行队列。在评估结果时必须考虑到这一点。
另请参阅
statistics(total_active_tasks)
、statistics(run_queue_lengths)
、statistics(run_queue_lengths_all)
、statistics(total_run_queue_lengths)
和statistics(total_run_queue_lengths_all)
。自 OTP 20.0 版本起可用
statistics(context_switches) -> {non_neg_integer(), 0}
返回自系统启动以来上下文切换的总次数。
statistics(exact_reductions) -> {Total :: non_neg_integer(), SinceLastCall :: non_neg_integer()}
返回精确的规约次数。
注意
statistics(exact_reductions)
是比 statistics(reductions) 更昂贵的操作。statistics(garbage_collection) -> { NumerOfGCs :: non_neg_integer(), WordsReclaimed :: non_neg_integer(), 0}
返回有关垃圾回收的信息,例如
> statistics(garbage_collection). {85,23961,0}
此信息对于某些实现可能无效。
statistics(io) -> {{input, non_neg_integer()}, {output, non_neg_integer()}}
返回
Input
,它是通过端口接收的总字节数,以及Output
,它是输出到端口的总字节数。statistics(microstate_accounting) -> [MSAcc_Thread]
微状态记账可用于测量 Erlang 运行时系统在执行各种任务上花费的时间。它被设计为尽可能轻量级,但启用此功能时会存在一些开销。微状态记账旨在作为一种性能分析工具,以帮助查找性能瓶颈。要
start
/stop
/reset
微状态记账,请使用系统标志microstate_accounting
。statistics(microstate_accounting)
返回一个表示 ERTS 中某些操作系统线程的映射列表。每个映射都包含type
和id
字段,可用于标识它是哪个线程,以及一个计数器字段,其中包含有关在各种状态下花费的时间的数据。示例
> erlang:statistics(microstate_accounting). [#{counters => #{aux => 1899182914, check_io => 2605863602, emulator => 45731880463, gc => 1512206910, other => 5421338456, port => 221631, sleep => 5150294100}, id => 1, type => scheduler}|...]
时间单位与
os:perf_counter/0
返回的时间单位相同。因此,要将其转换为毫秒,可以执行以下操作lists:map( fun(#{ counters := Cnt } = M) -> MsCnt = maps:map(fun(_K, PerfCount) -> erlang:convert_time_unit(PerfCount, perf_counter, 1000) end, Cnt), M#{ counters := MsCnt } end, erlang:statistics(microstate_accounting)).
请注意,这些值不能保证是每个状态中花费的确切时间。这是因为为了尽可能减少开销而进行了各种优化。
MSAcc_Thread_Type
sscheduler
- 执行大部分工作的主要执行线程。有关详细信息,请参阅erl +S。dirty_cpu_scheduler
- 用于长时间运行的 CPU 密集型工作的线程。有关详细信息,请参阅erl +SDcpu。dirty_io_scheduler
- 用于长时间运行的 I/O 工作的线程。有关详细信息,请参阅erl +SDio。async
- 异步线程由各种链接驱动程序(主要是文件驱动程序)用于卸载非 CPU 密集型工作。有关详细信息,请参阅erl +A。aux
- 处理任何未专门分配给调度器的工作。poll
- 为模拟器执行 I/O 轮询。有关详细信息,请参阅erl +IOt。
以下
MSAcc_Thread_State
s 可用。所有状态都是互斥的,这意味着一个线程不能同时处于两种状态。因此,如果将一个线程中所有计数器的数字相加,则会得到该线程的总运行时。aux
- 处理辅助作业所花费的时间。check_io
- 检查新 I/O 事件所花费的时间。emulator
- 执行 Erlang 进程所花费的时间。gc
- 执行垃圾回收所花费的时间。启用额外状态时,这是执行非完全扫描垃圾回收所花费的时间。other
- 执行未记账事项所花费的时间。port
- 执行端口所花费的时间。sleep
- 休眠所花费的时间。
可以通过配置添加更精细的
MSAcc_Thread_State
s(例如./configure --with-microstate-accounting=extra
)。禁用微状态记账时,启用这些状态会导致性能下降,并且在启用时会增加开销。alloc
- 管理内存所花费的时间。在没有额外状态的情况下,此时间会分散到所有其他状态。bif
- 在 BIF 中花费的时间。在没有额外状态的情况下,此时间是emulator
状态的一部分。busy_wait
- 忙等待所花费的时间。这也是使用statistics(scheduler_wall_time)
时调度器不再报告其处于活动状态的状态。因此,如果将除此状态和睡眠之外的所有其他状态相加,然后将其除以线程中的所有时间,则应该得到与scheduler_wall_time
分数非常相似的值。在没有额外状态的情况下,此时间是other
状态的一部分。ets
- 执行 ETS BIF 所花费的时间。在没有额外状态的情况下,此时间是emulator
状态的一部分。gc_full
- 执行完全扫描垃圾回收所花费的时间。在没有额外状态的情况下,此时间是gc
状态的一部分。nif
- 在 NIF 中花费的时间。在没有额外状态的情况下,此时间是emulator
状态的一部分。send
- 发送消息所花费的时间(仅限进程)。在没有额外状态的情况下,此时间是emulator
状态的一部分。timers
- 管理计时器所花费的时间。在没有额外状态的情况下,此时间是other
状态的一部分。
实用程序模块
msacc
可用于更轻松地分析这些统计信息。如果系统标志
microstate_accounting
被禁用,则返回undefined
。线程信息列表是无序的,并且在调用之间可能会以不同的顺序出现。
注意
线程和状态可能会在没有任何事先通知的情况下发生更改。
自 OTP 19.0 版本起可用
statistics(reductions) -> {Reductions :: non_neg_integer(), SinceLastCall :: non_neg_integer()}
返回有关规约的信息,例如
> statistics(reductions). {2046,11}
变更
从 ERTS 5.5 (Erlang/OTP R11B) 开始,此值不包括在当前已调度进程的当前时间片中执行的规约。如果需要精确的值,请使用
statistics(exact_reductions)
。statistics(run_queue) -> non_neg_integer()
返回所有普通和脏 CPU 运行队列的总长度。也就是说,排队的工作负载预计是 CPU 绑定的。这些信息是原子收集的。也就是说,结果是状态的一致快照,但与
statistics(total_run_queue_lengths)
相比,此操作的成本要高得多,尤其是在使用大量调度器时。statistics(run_queue_lengths) -> [non_neg_integer()]
返回与
statistics(run_queue_lengths_all)
相同的值,但脏 IO 运行队列的信息不包含在结果中。也就是说,只有预计是 CPU 绑定的工作负载的运行队列才会包含在结果中。自 OTP 18.3 起可用
statistics(run_queue_lengths_all) -> [non_neg_integer()]
返回一个列表,其中每个元素表示每个运行队列中准备运行的进程和端口的数量。普通运行队列的值位于结果列表的开头。第一个元素对应于调度器编号 1 的普通运行队列,依此类推。如果支持脏调度器,则脏 CPU 运行队列和脏 IO 运行队列的值(按此顺序)将跟在最后。这些信息不是原子收集的。也就是说,结果不一定是状态的一致快照,而是以相当有效的方式收集的。
注意
每个普通调度器管理一个运行队列。如果支持脏调度器,所有脏 CPU 调度器共享一个运行队列,所有脏 IO 调度器共享一个运行队列。也就是说,我们有多个普通运行队列,一个脏 CPU 运行队列和一个脏 IO 运行队列。工作负载不能在不同类型的运行队列之间迁移。只有普通运行队列中的工作负载才能迁移到其他普通运行队列。在评估结果时必须考虑到这一点。
另请参阅
statistics(run_queue_lengths)
、statistics(total_run_queue_lengths_all)
、statistics(total_run_queue_lengths)
、statistics(active_tasks)
、statistics(active_tasks_all)
和statistics(total_active_tasks)
、statistics(total_active_tasks_all)
。自 OTP 20.0 版本起可用
statistics(runtime) -> {Total :: non_neg_integer(), SinceLastCall :: non_neg_integer()}
返回有关运行时(以毫秒为单位)的信息。
这是 Erlang 运行时系统中所有线程的运行时总和,因此可能大于挂钟时间。
警告
由于使用的操作系统提供的底层功能存在限制,此值可能会回绕。
示例
> statistics(runtime). {1690,1620}
statistics(scheduler_wall_time) -> [{Id :: pos_integer, ActiveTime :: non_neg_integer(), TotalTime :: non_neg_integer()}] | undefined
返回描述系统中普通和脏 CPU 调度器忙碌的时间的信息。此值通常比查看
top
或sysstat
等工具提供的 CPU 利用率更能指示 Erlang 节点的负载情况。这是因为scheduler_wall_time
还包括调度器正在等待其他资源(例如内部互斥锁)可用但不使用 CPU 的时间。为了更好地了解调度器在忙于做什么,您可以使用微状态记账。繁忙调度器的定义是当它不空闲且不忙等待新工作时,即
- 执行进程代码
- 执行链接驱动程序或 NIF 代码
- 执行 BIF 或任何其他运行时处理
- 垃圾回收
- 处理任何其他内存管理
请注意,即使操作系统已调度出调度器线程,调度器也可能处于繁忙状态。
注意
建议使用模块
scheduler
而不是直接使用此函数,因为它提供了一种更简单的方法来获取您通常想要的信息。如果启用此功能,它会返回一个元组列表,格式为
{SchedulerId, ActiveTime, TotalTime}
,其中SchedulerId
是调度器的整数 ID,ActiveTime
是调度器处于忙碌状态的持续时间,而TotalTime
是自scheduler_wall_time
为特定调度器激活以来的总时间。返回的时间单位未定义,并且可能在不同版本、操作系统和系统重启之间发生变化。scheduler_wall_time
仅用于计算调度器利用率的相对值。ActiveTime
永远不会超过TotalTime
。调度器信息列表是无序的,并且在调用之间可能以不同的顺序出现。如果 禁用此功能,则返回
undefined
。调度器之间的激活时间可能差异很大。目前,脏调度器在系统启动时激活,而正常调度器在
scheduler_wall_time
功能启用后的一段时间激活。此函数的返回值中仅包含预期处理 CPU 密集型工作的调度器的信息。如果您还需要有关脏 I/O 调度器的信息,请改用
statistics(scheduler_wall_time_all)
。正常调度器的调度器标识符范围为
1 =< SchedulerId =<
erlang:system_info(schedulers)
。脏 CPU 调度器的调度器标识符范围为erlang:system_info(schedulers) < SchedulerId =< erlang:system_info(schedulers) +
erlang:system_info(dirty_cpu_schedulers)
。注意
不同类型的调度器处理特定类型的工作。每个作业都分配给特定的调度器类型。作业可以在相同类型的不同调度器之间迁移,但永远不会在不同类型的调度器之间迁移。在评估返回的结果时必须考虑这一事实。
您可以使用
scheduler_wall_time
来计算调度器利用率。首先,您对erlang:statistics(scheduler_wall_time)
返回的值进行采样。> erlang:system_flag(scheduler_wall_time, true). false > Ts0 = lists:sort(erlang:statistics(scheduler_wall_time)), ok. ok
稍后,用户拍摄另一个快照并计算每个调度器的调度器利用率,例如
> Ts1 = lists:sort(erlang:statistics(scheduler_wall_time)), ok. ok > lists:map(fun({{I, A0, T0}, {I, A1, T1}}) -> {I, (A1 - A0)/(T1 - T0)} end, lists:zip(Ts0,Ts1)). [{1,0.9743474730177548}, {2,0.9744843782751444}, {3,0.9995902361669045}, {4,0.9738012596572161}, {5,0.9717956667018103}, {6,0.9739235846420741}, {7,0.973237033077876}, {8,0.9741297293248656}]
使用相同的快照来计算总的调度器利用率
> {A, T} = lists:foldl(fun({{_, A0, T0}, {_, A1, T1}}, {Ai,Ti}) -> {Ai + (A1 - A0), Ti + (T1 - T0)} end, {0, 0}, lists:zip(Ts0,Ts1)), TotalSchedulerUtilization = A/T. 0.9769136803764825
当所有调度器在两次测量之间始终处于活动状态时,总调度器利用率将等于
1.0
。另一个(可能更有用)的值是计算相对于最大可用 CPU 时间的加权总调度器利用率
> WeightedSchedulerUtilization = (TotalSchedulerUtilization * (erlang:system_info(schedulers) + erlang:system_info(dirty_cpu_schedulers))) / erlang:system_info(logical_processors_available). 0.9769136803764825
当调度器的活动时间与最大可用 CPU 时间相同时,此加权调度器利用率将达到
1.0
。如果存在的调度器多于可用的逻辑处理器,则此值可能大于1.0
。从 ERTS 版本 9.0 开始,Erlang 运行时系统默认情况下将拥有比逻辑处理器更多的调度器。这是由于脏调度器的原因。
注意
scheduler_wall_time
默认情况下处于禁用状态。要启用它,请使用erlang:system_flag(scheduler_wall_time, true)
。自 OTP R15B01 起可用
statistics(scheduler_wall_time_all) -> [{Id :: pos_integer, ActiveTime :: non_neg_integer(), TotalTime :: non_neg_integer()}] | undefined
等效于
statistics(scheduler_wall_time)
,但它还包括有关所有脏 I/O 调度器的信息。脏 I/O 调度器的调度器标识符范围为
erlang:system_info(schedulers)
+
erlang:system_info(dirty_cpu_schedulers)
< SchedulerId =< erlang:system_info(schedulers) + erlang:system_info(dirty_cpu_schedulers) +
erlang:system_info(dirty_io_schedulers)
。注意
请注意,在脏 I/O 调度器上执行的工作预计主要等待 I/O。也就是说,当您在脏 I/O 调度器上获得高调度器利用率时,由于这项工作,CPU 利用率预计不会很高。
自 OTP 20.0 版本起可用
statistics(total_active_tasks) -> non_neg_integer()
等效于调用
lists:sum(
statistics(active_tasks)
)
,但效率更高。自 OTP 18.3 起可用
statistics(total_active_tasks_all) -> non_neg_integer()
等效于调用
lists:sum(
statistics(active_tasks_all)
)
,但效率更高。自 OTP 20.0 版本起可用
statistics(total_run_queue_lengths) -> non_neg_integer()
等效于调用
lists:sum(
statistics(run_queue_lengths)
)
,但效率更高。自 OTP 18.3 起可用
statistics(total_run_queue_lengths_all) -> non_neg_integer()
等效于调用
lists:sum(
statistics(run_queue_lengths_all)
)
,但效率更高。自 OTP 20.0 版本起可用
statistics(wall_clock) -> {Total :: non_neg_integer(), SinceLastCall :: non_neg_integer()}
返回有关挂钟的信息。
wall_clock
可以以与runtime
相同的方式使用,不同之处在于测量的是实时时间,而不是运行时间或 CPU 时间。
-spec system_flag(backtrace_depth, Depth) -> OldDepth when Depth :: non_neg_integer(), OldDepth :: non_neg_integer(); (cpu_topology, CpuTopology) -> OldCpuTopology when CpuTopology :: cpu_topology(), OldCpuTopology :: cpu_topology(); (dirty_cpu_schedulers_online, DirtyCPUSchedulersOnline) -> OldDirtyCPUSchedulersOnline when DirtyCPUSchedulersOnline :: pos_integer(), OldDirtyCPUSchedulersOnline :: pos_integer(); (erts_alloc, {Alloc, F, V}) -> ok | notsup when Alloc :: atom(), F :: atom(), V :: integer(); (fullsweep_after, Number) -> OldNumber when Number :: non_neg_integer(), OldNumber :: non_neg_integer(); (microstate_accounting, Action) -> OldState when Action :: true | false | reset, OldState :: true | false; (min_heap_size, MinHeapSize) -> OldMinHeapSize when MinHeapSize :: non_neg_integer(), OldMinHeapSize :: non_neg_integer(); (min_bin_vheap_size, MinBinVHeapSize) -> OldMinBinVHeapSize when MinBinVHeapSize :: non_neg_integer(), OldMinBinVHeapSize :: non_neg_integer(); (max_heap_size, MaxHeapSize) -> OldMaxHeapSize when MaxHeapSize :: max_heap_size(), OldMaxHeapSize :: max_heap_size(); (multi_scheduling, BlockState) -> OldBlockState when BlockState :: block | unblock | block_normal | unblock_normal, OldBlockState :: blocked | disabled | enabled; (outstanding_system_requests_limit, NewLimit) -> OldLimit when NewLimit :: 1..134217727, OldLimit :: 1..134217727; (scheduler_bind_type, How) -> OldBindType when How :: scheduler_bind_type() | default_bind, OldBindType :: scheduler_bind_type(); (scheduler_wall_time, Boolean) -> OldBoolean when Boolean :: boolean(), OldBoolean :: boolean(); (schedulers_online, SchedulersOnline) -> OldSchedulersOnline when SchedulersOnline :: pos_integer(), OldSchedulersOnline :: pos_integer(); (system_logger, Logger) -> PrevLogger when Logger :: logger | undefined | pid(), PrevLogger :: logger | undefined | pid(); (trace_control_word, TCW) -> OldTCW when TCW :: non_neg_integer(), OldTCW :: non_neg_integer(); (time_offset, finalize) -> OldState when OldState :: preliminary | final | volatile; (internal_cpu_topology, term()) -> term(); (sequential_tracer, Tracer) -> PrevTracer | false when Tracer :: pid() | port() | {module(), term()} | false, PrevTracer :: pid() | port() | {module(), term()} | false; (reset_seq_trace, true) -> true.
将系统标志设置为给定的值。
可以设置的可能标志是
system_flag(backtrace_depths, non_neg_integer()) -> non_neg_integer()
设置
'EXIT'
元组的退出原因元素中回溯调用堆栈的最大深度。该标志还限制了process_info/2
项current_stacktrace
返回的堆栈跟踪深度。返回标志的旧值。
system_flag(cpu_topology, cpu_topology()) -> cpu_topology()
警告
此参数已弃用。 请使用命令行参数
+sct
在 erl 中,而不是使用此参数。当删除此参数时,将在模拟器启动时确定要使用的最终 CPU 拓扑。
设置用户定义的
CpuTopology
。用户定义的 CPU 拓扑会覆盖任何自动检测到的 CPU 拓扑。通过将undefined
作为CpuTopology
传递,系统将恢复为自动检测到的 CPU 拓扑。返回值等于更改之前从erlang:system_info(cpu_topology)
返回的值。返回标志的旧值。
在将调度器绑定到逻辑处理器时使用 CPU 拓扑。如果更改 CPU 拓扑时调度器已经绑定,则会向调度器发送请求以根据新的 CPU 拓扑重新绑定。
还可以通过将命令行参数
+sct
传递给 erl 来设置用户定义的 CPU 拓扑。有关
CpuTopology
类型和更多信息,请参见erlang:system_info(cpu_topology)
以及命令行标志+sct
和+sbt
在 erl 中。system_flag(dirty_cpu_schedulers_online, pos_integer()) -> pos_integer()
设置联机的脏 CPU 调度器的数量。范围是
1 <= DirtyCPUSchedulersOnline <= N
,其中N
是erlang:system_info(dirty_cpu_schedulers)
和erlang:system_info(schedulers_online)
的返回值中最小的值。返回标志的旧值。
如果联机的调度器数量发生变化,则联机的脏 CPU 调度器的数量可能会发生变化。例如,如果有 12 个调度器和 6 个脏 CPU 调度器联机,并且使用
system_flag/2
将联机的调度器数量设置为 6,则联机的脏 CPU 调度器的数量也会自动减少一半,降至 3。同样,联机的脏 CPU 调度器的数量会与联机的调度器数量的增加成比例地增加。有关更多信息,请参见
erlang:system_info(dirty_cpu_schedulers)
和erlang:system_info(dirty_cpu_schedulers_online)
。自 OTP 17.0 起可用
system_flag(erts_alloc, {Alloc :: atom(), F :: atom(), V :: integer()}) -> ok | notsup
为
erts_alloc(3)
设置系统标志。Alloc
是要影响的分配器,例如binary_alloc
。F
是要更改的标志,V
是新值。只能在运行时更改所有
erts_alloc
标志的子集。此子集当前仅为标志sbct
。如果设置了标志,则返回
ok
;如果erts_alloc
不支持,则返回notsup
。自 OTP 20.2.3 起可用
system_flag(fullsweep_after, non_neg_integer()) -> non_neg_integer()
设置系统标志
fullsweep_after
。Number
是一个非负整数,指示在强制执行完全垃圾收集之前可以执行多少次分代垃圾收集。该值适用于新进程,而正在运行的进程不受影响。返回标志的旧值。
在低内存系统(尤其是在没有虚拟内存的情况下)中,将该值设置为
0
可以帮助节省内存。也可以通过(OS)环境变量
ERL_FULLSWEEP_AFTER
设置此值。system_flag(microstate_accounting, true | false | reset) -> boolean()
打开/关闭微状态会计测量。当传递 reset 时,所有计数器都将重置为 0。
有关更多信息,请参见
statistics(microstate_accounting)
。自 OTP 19.0 版本起可用
system_flag(min_heap_size, non_neg_integer()) -> non_neg_integer()
设置进程的默认最小堆大小。大小以字为单位指定。新的
min_heap_size
仅影响在更改min_heap_size
之后生成的进程。可以使用spawn_opt/4
或process_flag/2
为单个进程设置min_heap_size
。返回标志的旧值。
system_flag(min_bin_vheap_size, non_neg_integer()) -> non_neg_integer()
设置进程的默认最小二进制虚拟堆大小。大小以字为单位指定。新的
min_bin_vhheap_size
仅影响在更改min_bin_vheap_size
之后生成的进程。可以使用spawn_opt/2,3,4
或process_flag/2
为单个进程设置min_bin_vheap_size
。返回标志的旧值。
自 OTP R13B04 起可用
system_flag(max_heap_size, max_heap_size()) -> max_heap_size()
设置进程的默认最大堆大小设置。大小以字为单位指定。新的
max_heap_size
仅影响在进行更改后生成的进程。可以使用spawn_opt/2,3,4
或process_flag/2
为单个进程设置max_heap_size
。返回标志的旧值。
有关堆如何增长的详细信息,请参阅 ERTS 内部文档中的 调整堆大小。
自 OTP 19.0 版本起可用
system_flag(multi_scheduling, BlockState) -> OldBlockState when BlockState :: block | unblock | block_normal | unblock_normal, OldBlockState :: blocked | disabled | enabled
如果启用了多调度,则模拟器将使用多个调度器线程。可以通过两种不同的方式阻止多调度。要么阻止除一个之外的所有调度器,要么阻止除一个之外的所有正常调度器。当仅阻止正常调度器时,脏调度器可以自由地继续调度进程。
如果
BlockState =:= block
,则会阻止多调度。也就是说,只会执行一个调度器线程。如果BlockState =:= unblock
并且没有其他人阻止多调度,并且此进程仅阻止了一次,则会解除多调度阻止。如果
BlockState =:= block_normal
,则会阻止正常多调度。也就是说,只会执行一个正常调度器线程,但可以执行多个脏调度器。如果BlockState =:= unblock_normal
并且没有其他人阻止正常多调度,并且此进程仅阻止了一次,则会解除正常多调度阻止。一个进程可以多次阻止多调度和正常多调度。如果一个进程多次阻止,则它必须解除阻止的次数与它阻止的次数完全相同,然后才能释放其多调度阻止。如果阻止多调度或正常多调度的进程退出,则它会自动释放其多调度和正常多调度的阻止。
返回值是
disabled
、blocked
、blocked_normal
或enabled
。 返回值描述了在调用erlang:system_flag(multi_scheduling, BlockState)
之后的状态。有关返回值的更多信息,请参阅erlang:system_info(multi_scheduling)
。注意
通常不需要阻塞多调度和正常多调度。 如果您认为需要使用这些功能,请再次考虑一下。 阻塞多调度只能作为最后的手段使用,因为它很可能是一种非常低效的问题解决方案。
另请参阅
erlang:system_info(multi_scheduling)
、erlang:system_info(normal_multi_scheduling_blockers)
、erlang:system_info(multi_scheduling_blockers)
和erlang:system_info(schedulers)
。system_flag(outstanding_system_requests_limit, 1..134217727) -> 1..134217727
设置一个限制,用于限制系统进程在编排系统范围内的更改时发出的未完成请求的数量。目前有两个这样的进程
代码清理器 - 代码清理器编排检查对旧代码的引用,然后再从系统中删除旧代码。
文字区域收集器 - 文字区域收集器编排从旧文字区域复制引用,然后再从系统中删除这些区域。
允许每个进程的未完成请求数量达到此限制。默认情况下,此限制设置为系统上 调度器 数量的两倍。这将确保调度器有足够的工作安排来尽可能快地执行这些操作,同时其他工作将与此工作交错进行。当前使用的限制可以通过调用
erlang:system_info(outstanding_system_requests_limit)
来检查。也可以通过将命令行参数
+zosrl <Limit>
传递给erl
来设置此限制。自 OTP 24.2 起可用
system_flag(scheduler_bind_type, scheduler_bind_type() | default_bind) -> scheduler_bind_type()
警告
此参数已弃用。 请使用命令行参数
+sbt
代替此参数。 在 erl 中。删除此参数后,将在仿真器启动时确定要使用的最终调度器绑定类型。控制调度器是否以及如何绑定到逻辑处理器。
当调用
erlang:system_flag(scheduler_bind_type, How)
时,会向所有在线调度器发送一个异步信号,导致它们尝试按请求绑定或解除绑定。注意
如果调度器绑定失败,通常会被静默忽略,因为并非总是可以验证有效的逻辑处理器标识符。如果报告了错误,则会记录错误事件。要验证调度器是否已按请求绑定,请调用
erlang:system_info(scheduler_bindings)
。调度器可以在较新的 Linux、Solaris、FreeBSD 和 Windows 系统上绑定,但在未来的版本中将支持更多系统。
为了使运行时系统能够绑定调度器,必须知道 CPU 拓扑。如果运行时系统无法自动检测 CPU 拓扑,则可以定义它。有关如何定义 CPU 拓扑的更多信息,请参阅 erl 中的命令行标志
+sct
。默认情况下,运行时系统不会将调度器绑定到逻辑处理器。
注意
如果 Erlang 运行时系统是唯一将线程绑定到逻辑处理器的操作系统进程,这将提高运行时系统的性能。但是,如果其他操作系统进程(例如,另一个 Erlang 运行时系统)也将线程绑定到逻辑处理器,则反而会产生性能损失。有时,这种性能损失可能很严重。如果是这样,建议不要绑定调度器。
调度器可以以不同的方式绑定。参数
How
确定调度器的绑定方式,并且可以是以下任何一种:thread_no_node_processor_spread
- 与 erl 中的命令行参数+sbt tnnps
相同。
返回值等于更改标志
scheduler_bind_type
之前的值How
。失败
notsup
- 如果不支持调度器绑定。badarg
- 如果How
不是记录的选项之一。badarg
- 如果 CPU 拓扑信息不可用。
也可以通过将命令行参数
+sbt
传递给 erl 来设置调度器绑定类型。有关更多信息,请参阅
erlang:system_info(scheduler_bind_type)
、erlang:system_info(scheduler_bindings)
以及 erl 中的命令行标志+sbt
和+sct
。system_flag(scheduler_wall_time, boolean()) -> boolean()
尝试通过传递
Boolean
作为true
或false
来启用或禁用调度器挂钟时间测量。有关如何使用调度器挂钟时间测量的更多信息,请参阅
statistics(scheduler_wall_time)
。调度器挂钟时间测量具有节点全局状态。它要么为节点上的所有进程启用,要么为所有进程禁用。每个进程都有一个初始化为零的逻辑计数器。将
Boolean
设置为true
的调用会将调用进程的计数器增加一步。将false
的调用会将其减少一步,除非它已经为零。只要至少有一个进程的计数器值大于零,scheduler_wall_time
的节点全局状态就会启用。当进程终止时,其计数器也会消失。为了确保scheduler_wall_time
保持启用,因此必须保持启用它的进程处于活动状态。返回节点全局状态的旧值,如果启用调度器挂钟时间测量则为
true
,如果禁用则为false
。调度器挂钟时间测量确实会消耗一些 CPU 开销,除非使用,否则不应保持开启状态。
自 OTP R15B01 起可用
system_flag(schedulers_online, pos_integer()) -> pos_integer()
设置在线调度器的数量。范围是
1 <= SchedulersOnline <= erlang:system_info(schedulers)
。返回标志的旧值。
如果仿真器构建时支持脏调度器,更改在线调度器的数量也可以更改在线脏 CPU 调度器的数量。 例如,如果 12 个调度器和 6 个脏 CPU 调度器在线,并且使用
system_flag/2
将在线调度器的数量设置为 6,则在线脏 CPU 调度器的数量也会自动减少一半,降至 3。 类似地,在线脏 CPU 调度器的数量与在线调度器数量的增加成比例增加。有关更多信息,请参阅
erlang:system_info(schedulers)
和erlang:system_info(schedulers_online)
。system_flag(system_logger, logger | undefined | pid()) -> logger | undefined | pid()
设置将接收 ERTS 生成的日志消息的进程。如果设置为
undefined
,则将丢弃 ERTS 生成的所有日志消息。消息的格式将为{log,Level,Format,ArgList,Metadata} where Level = atom(), Format = string(), ArgList = list(term()), Metadata = #{ pid => pid(), group_leader => pid(), time := logger:timestamp(), error_logger := #{ emulator := true, tag := atom() }
如果
system_logger
进程终止,则此标志将重置为logger
。默认值为名为
logger
的进程。返回标志的旧值。
注意
此函数旨在由 KERNEL
logger
使用。如果您将其更改为其他内容,请小心,因为日志消息可能会丢失。如果要拦截仿真器日志消息,请通过向 KERNEL 日志记录器添加专用处理程序来实现。自 OTP 21.2 起可用
system_flag(trace_control_word, non_neg_integer()) -> non_neg_integer()
将节点跟踪控制字的值设置为
TCW
,它应该是一个无符号整数。 有关更多信息,请参阅用户指南中“Erlang 中的匹配规范”部分中的函数set_tcw
。返回标志的旧值。
system_flag(time_offset, finalize) -> preliminary | final | volatile
当使用 单时间扭曲模式时,完成 时间偏移。 如果使用其他时间扭曲模式,则时间偏移状态将保持不变。
返回旧状态标识符,即
- 如果返回
preliminary
,则执行了最终确定,并且时间偏移现在是最终的。 - 如果返回
final
,则时间偏移已经处于最终状态。 这要么是因为另一个erlang:system_flag(time_offset, finalize)
调用,要么是因为使用了无时间扭曲模式。 - 如果返回
volatile
,则无法完成时间偏移,因为使用了 多时间扭曲模式。
自 OTP 18.0 起可用
- 如果返回
-spec system_info(allocated_areas) -> [tuple()]; (allocator) -> {Allocator, Version, Features, Settings} when Allocator :: undefined | glibc, Version :: [non_neg_integer()], Features :: [atom()], Settings :: [{Subsystem :: atom(), [{Parameter :: atom(), Value :: term()}]}]; ({allocator, Alloc}) -> [_] when Alloc :: atom(); (alloc_util_allocators) -> [Alloc] when Alloc :: atom(); ({allocator_sizes, Alloc}) -> [_] when Alloc :: atom(); (atom_count) -> pos_integer(); (atom_limit) -> pos_integer(); (build_type) -> opt | debug | gcov | valgrind | gprof | lcnt | frmptr; (c_compiler_used) -> {atom(), term()}; (check_io) -> [_]; (compat_rel) -> integer(); (cpu_topology) -> CpuTopology when CpuTopology :: cpu_topology(); ({cpu_topology, defined | detected | used}) -> CpuTopology when CpuTopology :: cpu_topology(); (cpu_quota) -> pos_integer() | unknown; (creation) -> integer(); (debug_compiled) -> boolean(); (delayed_node_table_gc) -> infinity | non_neg_integer(); (dirty_cpu_schedulers) -> non_neg_integer(); (dirty_cpu_schedulers_online) -> non_neg_integer(); (dirty_io_schedulers) -> non_neg_integer(); (dist) -> binary(); (dist_buf_busy_limit) -> non_neg_integer(); (dist_ctrl) -> [{Node :: node(), ControllingEntity :: port() | pid()}]; (driver_version) -> string(); (dynamic_trace) -> none | dtrace | systemtap; (dynamic_trace_probes) -> boolean(); (eager_check_io) -> boolean(); (emu_flavor) -> emu | jit; (emu_type) -> opt | debug | gcov | valgrind | gprof | lcnt | frmptr; (end_time) -> non_neg_integer(); (ets_count) -> pos_integer(); (ets_limit) -> pos_integer(); (fullsweep_after) -> {fullsweep_after, non_neg_integer()}; (garbage_collection) -> garbage_collection_defaults(); (heap_sizes) -> [non_neg_integer()]; (heap_type) -> private; (info) -> binary(); (kernel_poll) -> boolean(); (loaded) -> binary(); (logical_processors | logical_processors_available | logical_processors_online) -> unknown | pos_integer(); (machine) -> string(); (max_heap_size) -> {max_heap_size, MaxHeapSize :: max_heap_size()}; (message_queue_data) -> message_queue_data(); (min_heap_size) -> {min_heap_size, MinHeapSize :: pos_integer()}; (min_bin_vheap_size) -> {min_bin_vheap_size, MinBinVHeapSize :: pos_integer()}; (modified_timing_level) -> integer() | undefined; (multi_scheduling) -> disabled | blocked | blocked_normal | enabled; (multi_scheduling_blockers) -> [Pid :: pid()]; (nif_version) -> string(); (normal_multi_scheduling_blockers) -> [Pid :: pid()]; (otp_release) -> string(); (os_monotonic_time_source) -> [{atom(), term()}]; (os_system_time_source) -> [{atom(), term()}]; (outstanding_system_requests_limit) -> 1..134217727; (port_parallelism) -> boolean(); (port_count) -> non_neg_integer(); (port_limit) -> pos_integer(); (process_count) -> pos_integer(); (process_limit) -> pos_integer(); (procs) -> binary(); (scheduler_bind_type) -> scheduler_bind_type(); (scheduler_bindings) -> tuple(); (scheduler_id) -> SchedulerId :: pos_integer(); (schedulers | schedulers_online) -> pos_integer(); (smp_support) -> boolean(); (start_time) -> integer(); (system_architecture) -> string(); (system_logger) -> logger | undefined | pid(); (system_version) -> string(); (threads) -> boolean(); (thread_pool_size) -> non_neg_integer(); (time_correction) -> true | false; (time_offset) -> preliminary | final | volatile; (time_warp_mode) -> no_time_warp | single_time_warp | multi_time_warp; (tolerant_timeofday) -> enabled | disabled; (trace_control_word) -> non_neg_integer(); (update_cpu_info) -> changed | unchanged; (version) -> string(); (wordsize | {wordsize, internal} | {wordsize, external}) -> 4 | 8; (async_dist) -> boolean(); (halt_flush_timeout) -> non_neg_integer() | infinity.
返回有关当前系统的信息。
此函数的文档分为以下几个部分,以便更容易导航。
内存分配
-allocated_areas
,allocator
,alloc_util_allocators
,allocator_sizes
进程信息
-fullsweep_after
,garbage_collection
,heap_sizes
,heap_type
,max_heap_size
,message_queue_data
,min_heap_size
,min_bin_vheap_size
,procs
系统限制
-atom_count
,atom_limit
,ets_count
,ets_limit
,port_count
,port_limit
,process_count
,process_limit
系统时间
-end_time
,os_monotonic_time_source
,os_system_time_source
,start_time
,time_correction
,time_offset
,time_warp_mode
,tolerant_timeofday
调度器信息
-dirty_cpu_schedulers
,dirty_cpu_schedulers_online
,dirty_io_schedulers
,multi_scheduling
,multi_scheduling_blockers
,normal_multi_scheduling_blockers
,scheduler_bind_type
,scheduler_bindings
,scheduler_id
,schedulers
,smp_support
,threads
,thread_pool_size
分布式信息
-creation
,delayed_node_table_gc
,dist
,dist_buf_busy_limit
,dist_ctrl
系统信息
-c_compiler_used
,check_io
,compat_rel
,debug_compiled
,driver_version
,dynamic_trace
,dynamic_trace_probes
,emu_flavor
,emu_type
,info
,kernel_poll
,loaded
,machine
,modified_timing_level
,nif_version
,otp_release
,outstanding_system_requests_limit
,port_parallelism
,system_architecture
,system_logger
,system_version
,trace_control_word
,version
,wordsize
内存分配
返回当前系统(仿真器)内存分配器的各种信息,由 Item
指定
allocated_areas
- 返回[tuple()]
,其中包含有关各种已分配内存区域的信息。每个元组的第一个元素是描述内存类型的原子,第二个元素是已分配内存的字节数。当存在有关已分配和已使用内存的信息时,还会存在第三个元素,其中包含已使用内存的字节数。
erlang:system_info(allocated_areas)
用于调试,其内容高度依赖于实现。因此,在需要时,结果的内容会更改,恕不另行通知。请注意,这些值的总和不是仿真器分配的总内存量。某些值是其他值的一部分,并且某些内存区域不属于结果的一部分。有关仿真器分配的总内存量的信息,请参阅
erlang:memory/0,1
。
allocator
- 返回{Allocator :: undefined | glibc, Version :: [non_neg_integer()], Features :: [atom()], Settings :: [{Subsystem :: atom(), [{Parameter :: atom(), Value :: term()}] }] }
其中
Allocator
对应于使用的malloc()
实现。如果Allocator
等于undefined
,则无法识别使用的malloc()
实现。可以识别glibc
。Version
是表示使用的malloc()
实现版本的整数列表(但不是字符串)。Features
是表示所用分配功能的原子列表。Settings
是子系统、其可配置参数和使用值的列表。设置在不同的平台、分配器和分配功能组合之间可能有所不同。内存大小以字节为单位给出。
另请参阅
erts_alloc(3)
中的“影响erts_alloc的系统标志”。{allocator, Alloc}
- 返回有关指定分配器的信息。从 ERTS 5.6.1 开始,返回值是{instance, InstanceNo, InstanceInfo}
元组的列表,其中InstanceInfo
包含有关分配器特定实例的信息。如果Alloc
不是已识别的分配器,则返回undefined
。如果Alloc
被禁用,则返回false
。请注意,返回的信息高度依赖于实现,并且可以随时更改或删除,恕不另行通知。它最初旨在作为开发新分配器时的工具,但由于它可能对其他人有兴趣,因此已进行了简要记录。
已识别的分配器在
erts_alloc(3)
中列出。有关超级载体的信息可以从 ERTS 8.0 中使用{allocator, erts_mmap}
或从 ERTS 5.10.4 中获取;当使用{allocator, mseg_alloc}
调用时返回的列表还包括一个{erts_mmap, _}
元组作为列表中的一个元素。阅读
erts_alloc(3)
文档后,返回的信息或多或少不言自明,但值得解释一些事情。调用计数由两个值表示,第一个值是千兆调用,第二个值是调用。mbcs
和sbcs
分别表示多块载体和单块载体。大小以字节为单位表示。当不显示大小时,它是某种东西的数量。大小和数量通常由三个值表示- 第一个是当前值。
- 第二个是自上次调用
erlang:system_info({allocator, Alloc})
以来最大值。 - 第三个是自仿真器启动以来的最大值。
如果仅存在一个值,则为当前值。
fix_alloc
内存块类型由两个值表示。第一个值是内存池大小,第二个值是已使用的内存大小。alloc_util_allocators
- 返回所有使用 ERTS 内部alloc_util
框架的分配器的名称的列表,作为原子。有关更多信息,请参阅erts_alloc(3)
中的 alloc_util 框架部分。{allocator_sizes, Alloc}
- 返回指定分配器的各种大小信息。返回的信息是erlang:system_info({allocator, Alloc})
返回的信息的子集。
CPU 拓扑
返回当前系统(仿真器)的 CPU 拓扑的各种信息,由 Item
指定
cpu_topology
- 返回仿真器当前使用的t:cpu_topology()
。CPU 拓扑用于将调度器绑定到逻辑处理器。使用的 CPU 拓扑是用户定义的 CPU 拓扑(如果存在),否则是自动检测到的 CPU 拓扑(如果存在)。如果不存在 CPU 拓扑,则返回undefined
。{cpu_topology, defined}
- 返回用户定义的t:cpu_topology()
。更多信息,请参考erl(1)
中的命令行标志+sct
以及参数cpu_topology
。{cpu_topology, detected}
- 返回自动检测到的t:cpu_topology()
。模拟器会在一些较新的 Linux、Solaris、FreeBSD 和 Windows 系统上检测 CPU 拓扑。在拥有超过 32 个逻辑处理器的 Windows 系统上,不会检测 CPU 拓扑。更多信息,请参考参数
cpu_topology
。{cpu_topology, used}
- 返回模拟器使用的CpuTopology
。更多信息,请参考参数cpu_topology
。logical_processors
- 返回系统中配置的检测到的逻辑处理器数量。返回值要么是整数,要么是原子unknown
,如果模拟器无法检测到配置的逻辑处理器。logical_processors_available
- 返回 Erlang 运行时系统可用的检测到的逻辑处理器数量。返回值要么是整数,要么是原子unknown
,如果模拟器无法检测到可用的逻辑处理器。可用逻辑处理器的数量小于或等于 在线逻辑处理器的数量。logical_processors_online
- 返回系统中在线的检测到的逻辑处理器数量。返回值要么是整数,要么是原子unknown
,如果模拟器无法检测到在线逻辑处理器。在线逻辑处理器的数量小于或等于 配置的逻辑处理器的数量。cpu_quota
- 返回模拟器受限的检测到的 CPU 配额。返回值是一个整数,表示我们获得了多少个处理器的运行时(介于 1 和逻辑处理器数量之间),如果模拟器无法检测到配额,则返回原子unknown
。update_cpu_info
- 运行时系统重新读取可用的 CPU 信息,并更新其内部存储的关于 检测到的 CPU 拓扑 和逻辑处理器数量的 配置、在线、可用 和 CPU 配额信息。如果自上次读取 CPU 信息以来,CPU 信息已更改,则返回原子
changed
,否则返回原子unchanged
。如果 CPU 信息已更改,您可能需要 调整在线调度器的数量。通常,您希望在线的调度器数量与 可用逻辑处理器的数量一样多。自从: OTP R14B
进程信息
返回有关默认进程堆设置的信息
fullsweep_after
- 返回{fullsweep_after, integer() >= 0}
,这是默认使用的fullsweep_after
垃圾回收设置。有关更多信息,请参阅下面描述的garbage_collection
。garbage_collection
- 返回garbage_collection_defaults/0
,描述默认的垃圾回收设置。本地节点上通过spawn
或spawn_link
生成的进程使用这些垃圾回收设置。可以使用erlang:system_flag/2
更改默认设置。spawn_opt/2,3,4
可以生成不使用默认设置的进程。heap_sizes
- 返回一个表示有效堆大小(以字为单位)的整数列表。所有 Erlang 堆的大小都来自此列表中的大小。heap_type
- 返回当前模拟器使用的堆类型。存在一种堆类型private
- 每个进程都有一个为自己保留的堆,并且不允许不同进程的堆之间存在引用。进程之间传递的消息在堆之间复制。
max_heap_size
- 返回{max_heap_size, MaxHeapSize}
,其中MaxHeapSize
是当前系统范围内生成的进程的最大堆大小设置。可以使用命令行标志+hmax
、+hmaxk
、+hmaxel
和+hmaxibl
在erl(1)
中设置此设置。也可以在运行时使用erlang:system_flag(max_heap_size, MaxHeapSize)
更改它。有关max_heap_size
进程标志的更多详细信息,请参阅process_flag(max_heap_size, MaxHeapSize)
。自:OTP 19.0
message_queue_data
- 返回message_queue_data
进程标志的默认值,它可以是off_heap
或on_heap
。默认值由erl(1)
中的命令行参数+hmqd
设置。有关更多信息,请参阅process_flag(message_queue_data, MQD)
的文档。自:OTP 19.0
min_heap_size
- 返回{min_heap_size, MinHeapSize}
,其中MinHeapSize
是当前系统范围内生成的进程的最小堆大小。自从: OTP R13B04
min_bin_vheap_size
- 返回{min_bin_vheap_size, MinBinVHeapSize}
,其中MinBinVHeapSize
是当前系统范围内生成的进程的最小二进制虚拟堆大小。自从: OTP R13B04
procs
- 返回一个二进制数据,其中包含格式化为 Erlang 崩溃转储中的进程和端口信息字符串。有关更多信息,请参阅用户指南中的 如何解释 Erlang 崩溃转储 部分。
系统限制
返回由 Item
指定的当前系统(模拟器)限制的信息
atom_count
- 返回当前本地节点上存在的原子数量。该值以整数形式给出。自从: OTP 20.0
atom_limit
- 返回允许的最大原子数。可以通过向erl(1)
传递命令行标志+t
在启动时增加此限制。自从: OTP 20.0
ets_count
- 返回当前本地节点上存在的 ETS 表的数量。自从: OTP 21.1
ets_limit
- 返回 ETS 表数量的限制。此限制部分过时,表的数量仅受可用内存的限制。自从: OTP R16B03
port_count
- 返回当前本地节点上存在的端口数量。该值以整数形式给出。这与length(erlang:ports())
返回的值相同,但效率更高。自:OTP R16B
port_limit
- 返回本地节点上同时存在的最大端口数,以整数形式表示。可以使用erl(1)
中的命令行标志+Q
在启动时配置此限制。自从 OTP R16B
process_count
- 返回当前本地节点上存在的进程数量。该值以整数形式给出。这与length(processes())
返回的值相同,但效率更高。process_limit
- 返回本地节点上同时存在的最大进程数。该值以整数形式给出。可以使用erl(1)
中的命令行标志+P
在启动时配置此限制。
系统时间
返回由 Item
指定的当前系统(模拟器)时间的信息
end_time
- 当前 Erlang 运行时系统实例中可以在内部表示的最后一个 Erlang 单调时间,以native
时间单位表示。 开始时间和结束时间之间的时间至少是一个世纪的四分之一。自从: OTP 18.0
os_monotonic_time_source
- 返回一个列表,其中包含有关运行时系统使用的 OS 单调时间来源的信息。如果返回
[]
,则表示没有可用的 OS 单调时间。该列表包含以Key
作为第一个元素,Value
作为第二个元素的二元组。这些元组的顺序未定义。以下元组可以作为列表的一部分,但将来可能会引入更多元组{function, Function}
-Function
是所用函数的名称。如果运行时系统可以使用 OS 单调时间,则此元组始终存在。{clock_id, ClockId}
- 仅当Function
可以与不同的时钟一起使用时,此元组才存在。ClockId
对应于调用Function
时使用的时钟标识符。{resolution, OsMonotonicTimeResolution}
- 当前 OS 单调时间源的最高可能分辨率,以每秒多少部分表示。如果无法从 OS 检索分辨率信息,则将OsMonotonicTimeResolution
设置为Function
返回值的时间单位的分辨率。也就是说,实际分辨率可能低于OsMonotonicTimeResolution
。请注意,分辨率不代表准确度,也不代表精度是否与分辨率一致。但是,您确实知道精度不会高于OsMonotonicTimeResolution
。{used_resolution, UsedOsMonotonicTimeResolution}
- 运行时系统使用的 OS 单调时间分辨率。这通常与OsMonotonicTimeResolution
相同。但是,在某些系统上,必须降低分辨率才能可靠地生成单调时间戳。例如,当在 Windows 上将QueryPerformanceCounter()
用作 OS 单调时间源时。如果进行了这样的分辨率降低,则UsedOsMonotonicTimeResolution
将小于OsMonotonicTimeResolution
。{extended, Extended}
- 如果时间值的范围已扩展,则Extended
等于yes
;否则,Extended
等于no
。如果Function
返回的值快速包装,则必须扩展范围。当返回值是 32 位值时,通常会出现这种情况。{parallel, Parallel}
- 如果Function
从多个线程并行调用,则Parallel
等于yes
。如果由于调用必须串行化而未并行调用,则Parallel
等于no
。{time, OsMonotonicTime}
-OsMonotonicTime
等于当前操作系统单调时间,单位为native
时间单位。
自从: OTP 18.0
os_system_time_source
- 返回一个列表,其中包含有关运行时系统使用的 OS 系统时间来源的信息。该列表包含以
Key
作为第一个元素,以Value
作为第二个元素的二元组。这些元组的顺序未定义。以下元组可以作为列表的一部分,但将来可能会引入更多元组{function, Function}
-Function
是所用函数的名称。{clock_id, ClockId}
- 仅当Function
可以与不同的时钟一起使用时才存在。ClockId
对应于调用Function
时使用的时钟标识符。{resolution, OsSystemTimeResolution}
- 当前 OS 系统时间源的最高可能的 分辨率,以每秒的份数表示。如果无法从操作系统检索分辨率信息,则OsSystemTimeResolution
将设置为Function
的返回值的 时间单位的分辨率。也就是说,实际分辨率可能低于OsSystemTimeResolution
。请注意,分辨率并不说明 准确性 或 精度 是否与分辨率对齐。但是,您知道精度不会比OsSystemTimeResolution
好。{parallel, Parallel}
- 如果Function
从多个线程并行调用,则Parallel
等于yes
。如果由于调用需要串行化而未并行调用,则Parallel
等于no
。{time, OsSystemTime}
-OsSystemTime
等于当前操作系统系统时间,单位为native
时间单位。
自从: OTP 18.0
start_time
- 当前 Erlang 运行时系统实例启动时的native
时间单位的 Erlang 单调时间。另请参阅
erlang:system_info(end_time)
。自从: OTP 18.0
time_correction
- 返回一个t:boolean()
值,指示是否启用了 时间校正。自从: OTP 18.0
time_offset
- 返回时间偏移的状态preliminary
- 时间偏移是初步的,稍后将更改并最终确定。初步时间偏移在 单时间扭曲模式的初步阶段使用。final
- 时间偏移是最终的。这要么是因为使用了 无时间扭曲模式,要么是因为在使用 单时间扭曲模式时时间偏移已最终确定。volatile
- 时间偏移是不稳定的。也就是说,它可以随时更改。这是因为使用了 多时间扭曲模式。
自从: OTP 18.0
time_warp_mode
- 返回一个标识所使用的 时间扭曲模式的值自从: OTP 18.0
tolerant_timeofday
- 返回是否为系统时间的突然变化启用enabled
或disabled
兼容 ERTS 7.0 之前的补偿。当 时间偏移 为final
且启用 时间校正 时,将enabled
此类补偿。自从:OTP 17.1
调度器信息
返回当前系统中关于调度器、调度和线程的信息,由 Item
指定
dirty_cpu_schedulers
- 返回模拟器使用的脏 CPU 调度器线程的数量。脏 CPU 调度器执行 CPU 密集型原生函数,例如 NIF、链接驱动程序代码和无法由正常模拟器调度器干净管理的 BIF。脏 CPU 调度器线程的数量在模拟器启动时确定,之后无法更改。但是,在线的脏 CPU 调度器线程的数量可以随时更改。可以通过在
erl(1)
中传递命令行标志+SDcpu
或+SDPcpu
在启动时设置脏 CPU 调度器的数量。另请参阅
erlang:system_flag(dirty_cpu_schedulers_online, DirtyCPUSchedulersOnline)
、erlang:system_info(dirty_cpu_schedulers_online)
、erlang:system_info(dirty_io_schedulers)
、erlang:system_info(schedulers)
、erlang:system_info(schedulers_online)
和erlang:system_flag(schedulers_online, SchedulersOnline)
。自从:OTP 17.0
dirty_cpu_schedulers_online
- 返回在线的脏 CPU 调度器的数量。返回值满足1 <= DirtyCPUSchedulersOnline <= N
,其中N
是erlang:system_info(dirty_cpu_schedulers)
和erlang:system_info(schedulers_online)
的最小返回值。可以通过在
erl(1)
中传递命令行标志+SDcpu
在启动时设置在线的脏 CPU 调度器的数量。有关详细信息,请参阅
erlang:system_info(dirty_cpu_schedulers)
、erlang:system_info(dirty_io_schedulers)
、erlang:system_info(schedulers_online)
和erlang:system_flag(dirty_cpu_schedulers_online, DirtyCPUSchedulersOnline)
。自从:OTP 17.0
dirty_io_schedulers
- 返回脏 I/O 调度器的数量,以整数形式表示。脏 I/O 调度器执行 I/O 密集型原生函数,例如 NIF 和链接驱动程序代码,这些函数无法由正常模拟器调度器干净管理。可以通过在
erl(1)
中传递命令行参数+SDio
在启动时设置此值。有关详细信息,请参阅
erlang:system_info(dirty_cpu_schedulers)
、erlang:system_info(dirty_cpu_schedulers_online)
和erlang:system_flag(dirty_cpu_schedulers_online, DirtyCPUSchedulersOnline)
。自从:OTP 17.0
multi_scheduling
- 返回以下之一disabled
- 模拟器已启动,只有一个调度器线程。blocked
- 模拟器有多个调度器线程,但除一个以外的所有调度器线程都被阻塞。也就是说,只有一个调度器线程调度 Erlang 进程并执行 Erlang 代码。blocked_normal
- 模拟器有多个调度器线程,但除一个以外的所有正常调度器线程都被阻塞。请注意,脏调度器不会被阻塞,并且可以调度 Erlang 进程并执行原生代码。enabled
- 模拟器有多个调度器线程,并且没有调度器线程被阻塞。也就是说,所有可用的调度器线程都调度 Erlang 进程并执行 Erlang 代码。
另请参阅
erlang:system_flag(multi_scheduling, BlockState)
、erlang:system_info(multi_scheduling_blockers)
、erlang:system_info(normal_multi_scheduling_blockers)
和erlang:system_info(schedulers)
。multi_scheduling_blockers
- 当多重调度被阻塞时返回Pid
列表,否则返回空列表。列表中的Pid
代表当前阻塞多重调度的所有进程。一个Pid
在列表中只出现一次,即使相应的进程已被多次阻塞。另请参阅
erlang:system_flag(multi_scheduling, BlockState)
、erlang:system_info(multi_scheduling)
、erlang:system_info(normal_multi_scheduling_blockers)
和erlang:system_info(schedulers)
。normal_multi_scheduling_blockers
- 当正常多重调度被阻塞时(即,除一个之外的所有正常调度器都被阻塞)返回Pid
列表,否则返回空列表。列表中的Pid
代表当前阻塞正常多重调度的所有进程。一个Pid
在列表中只出现一次,即使相应的进程已被多次阻塞。另请参阅
erlang:system_flag(multi_scheduling, BlockState)
、erlang:system_info(multi_scheduling)
、erlang:system_info(multi_scheduling_blockers)
和erlang:system_info(schedulers)
。自:OTP 19.0
scheduler_bind_type
- 返回t:scheduler_bind_type()
,有关用户如何请求绑定或不绑定调度器的信息。请注意,尽管用户已请求绑定调度器,但它们可能会静默地绑定失败。要检查调度器绑定,请调用
erlang:system_info(scheduler_bindings)
。有关详细信息,请参阅
erl(1)
中的命令行参数+sbt
和erlang:system_info(scheduler_bindings)
。scheduler_bindings
- 返回有关当前使用的调度器绑定的信息。返回一个元组,其大小等于
erlang:system_info(schedulers)
。元组的元素是整数或原子unbound
。逻辑处理器标识符表示为整数。元组的第N
个元素等于调度器标识符等于N
的调度器的当前绑定。例如,如果调度器已绑定,则element(erlang:system_info(scheduler_id), erlang:system_info(scheduler_bindings))
返回调用进程正在其上执行的逻辑处理器的标识符。请注意,只有在线的调度器才能绑定到逻辑处理器。
有关更多信息,请参阅
erl(1)
中的命令行参数+sbt
和erlang:system_info(schedulers_online)
。scheduler_id
- 返回调用进程正在其上执行的调度器线程的调度器 ID(SchedulerId
)。SchedulerId
是一个正整数,其中1 <= SchedulerId <= erlang:system_info(schedulers)
。schedulers
- 返回仿真器使用的调度器线程数。在线调度器线程调度 Erlang 进程和 Erlang 端口,并执行 Erlang 代码和 Erlang 链接驱动程序代码。调度器线程的数量在仿真器启动时确定,以后无法更改。但是,在线调度器的数量可以随时更改。
另请参阅
erlang:system_flag(schedulers_online, SchedulersOnline)
、erlang:system_info(schedulers_online)
、erlang:system_info(scheduler_id)
、erlang:system_flag(multi_scheduling, BlockState)
、erlang:system_info(multi_scheduling)
、erlang:system_info(normal_multi_scheduling_blockers)
和erlang:system_info(multi_scheduling_blockers)
。schedulers_online
- 返回在线调度器的数量。在线调度器的调度器标识符满足关系1 <= SchedulerId <= erlang:system_info(schedulers_online)
。有关更多信息,请参阅
erlang:system_info(schedulers)
和erlang:system_flag(schedulers_online, SchedulersOnline)
。smp_support
- 返回true
。threads
- 返回true
。thread_pool_size
- 返回用于异步驱动程序调用的异步线程池中的异步线程数(erl_driver:driver_async()
)。该值以整数形式给出。
分发信息
返回当前系统中由 Item
指定的有关 Erlang 分发的信息。
async_dist
- 返回运行时系统使用的命令行参数 +pad <boolean> 的值。此值确定新生成进程的默认async_dist
值。起始于:OTP 25.3
creation
- 将本地节点的“创建”值作为整数返回。当节点重新启动时,创建会更改。节点的创建存储在进程标识符、端口标识符和引用中。这使得可以区分来自节点不同实例的标识符。创建值当前为 32 位正整数,但这在未来版本中可能会更改。如果节点未启动,则返回0
。delayed_node_table_gc
- 返回节点表中条目的垃圾回收延迟的时间量(以秒为单位)。此限制可以在启动时通过将命令行标志+zdntgc
传递给erl(1)
来设置。有关更多信息,请参阅命令行标志的文档。自从: OTP 18.0
dist
- 返回一个二进制文件,其中包含格式化为 Erlang 崩溃转储的分发信息字符串。有关更多信息,请参阅用户指南中的 如何解释 Erlang 崩溃转储部分。dist_buf_busy_limit
- 返回分发缓冲区繁忙限制的值(以字节为单位)。此限制可以在启动时通过将命令行标志+zdbbl
传递给erl(1)
来设置。起始于:OTP R14B01
dist_ctrl
- 返回一个元组列表{Node :: node(), ControllingEntity :: port() | pid()}
,每个连接的远程节点一个条目。Node
是节点名称,ControllingEntity
是负责与该节点通信的端口或进程标识符。更具体地说,通过 TCP/IP 连接的节点(正常情况)的ControllingEntity
是与特定节点通信中使用的套接字。
系统信息
返回当前系统(仿真器)的各种信息,如 Item
指定。
c_compiler_used
- 返回一个二元组,描述编译运行时系统时使用的 C 编译器。第一个元素是一个描述编译器名称的原子,如果未知,则为undefined
。第二个元素是一个描述编译器版本的术语,如果未知,则为undefined
。check_io
- 返回一个列表,其中包含有关仿真器内部 I/O 检查的杂项信息。请注意,返回列表的内容可能会因平台和时间而异。仅保证返回一个列表。compat_rel
- 将本地节点的兼容模式作为整数返回。返回的整数表示当前仿真器已设置为向后兼容的 Erlang/OTP 版本。可以使用erl(1)
中的命令行标志+R
在启动时配置兼容模式。debug_compiled
- 如果仿真器已调试编译,则返回true
,否则返回false
。driver_version
- 返回一个字符串,其中包含运行时系统使用的 Erlang 驱动程序版本。它具有 "<major ver>.<minor ver>" 的形式。dynamic_trace
- 返回一个原子,描述编译到虚拟机中的动态跟踪框架。它可以是dtrace
、systemtap
或none
。对于商业或标准版本,它始终为none
。其他返回值表示自定义配置(例如,./configure --with-dynamic-trace=dtrace
)。有关动态跟踪的更多信息,请参阅dyntrace(3)
手册页以及 Erlang 源代码顶级目录中的README.dtrace
/README.systemtap
文件。起始于:OTP R15B01
dynamic_trace_probes
- 返回一个t:boolean()
,指示动态跟踪探测(dtrace
或systemtap
)是否构建到仿真器中。只有当虚拟机是为动态跟踪而构建的(即system_info(dynamic_trace)
返回dtrace
或systemtap
)时,它才可能为true
。起始于:OTP R15B01
emu_flavor
- 返回一个原子,描述运行时系统的风格。这将是emu
或jit
。可能会在不事先通知的情况下随时添加或删除可能的返回值。起始于:OTP 24.0
emu_type
- 返回一个原子,描述运行时系统的构建类型。这通常是优化的原子opt
。其他可能的返回值是debug
、gcov
、valgrind
、gprof
和lcnt
。可能会在不事先通知的情况下随时添加或删除可能的返回值。起始于:OTP 24.0
halt_flush_timeout
- 返回由erl
+zhft <Timeout>
命令行标志设置的默认停止刷新超时。自:OTP 27.0
info
- 返回一个二进制文件,其中包含格式化为 Erlang 崩溃转储的杂项系统信息字符串。有关更多信息,请参阅用户指南中的 如何解释 Erlang 崩溃转储部分。kernel_poll
- 如果仿真器使用某种内核轮询实现,则返回true
,否则返回false
。loaded
- 返回一个二进制文件,其中包含格式化为 Erlang 崩溃转储的已加载模块信息字符串。有关更多信息,请参阅用户指南中的 如何解释 Erlang 崩溃转储部分。machine
- 返回一个包含 Erlang 机器名称的字符串。modified_timing_level
- 如果启用修改后的计时,则返回修改后的计时级别(t:integer()
),否则返回undefined
。有关修改后计时的更多信息,请参阅erl(1)
中的命令行标志+T
nif_version
- 返回一个字符串,其中包含运行时系统使用的 Erlang NIF 接口的版本。它的形式为“<major ver>.<minor ver>”。起始于:OTP 17.4
otp_release
- 返回一个字符串,其中包含当前正在执行的 ERTS 应用程序所属的 OTP 版本的 OTP 发行号。从 Erlang/OTP 17 开始,OTP 发行号对应于主要 OTP 版本号。没有
erlang:system_info()
参数给出确切的 OTP 版本。这是因为在一般情况下,很难确定确切的 OTP 版本。有关更多信息,请参阅系统文档中 系统原则中版本的描述。outstanding_system_requests_limit
- 返回由系统进程编排系统范围更改时,未完成请求的数量限制。有关更多信息,请参阅erlang:system_flag(outstanding_system_requests_limit, Limit)
。自从:OTP 24.2
port_parallelism
- 返回所使用的默认端口并行调度提示。有关更多信息,请参阅erl(1)
中的命令行参数+spp
。自:OTP R16B
system_architecture
- 返回一个字符串,其中包含模拟器构建时所用的处理器和操作系统架构。system_logger
- 返回由erlang:system_flag(system_logger, *)
设置的当前system_logger
。自从:OTP 21.3
system_version
- 返回一个字符串,其中包含版本号和一些重要属性,例如调度器的数量。trace_control_word
- 返回节点跟踪控制字的值。有关更多信息,请参阅用户指南中 Erlang 中的匹配规范部分中的函数get_tcw
。version
- 返回一个字符串,其中包含模拟器的版本号。wordsize
- 与{wordsize, internal}
相同。{wordsize, internal}
- 以整数形式返回 Erlang 术语字的大小(以字节为单位),即在 32 位架构上返回 4,在 64 位架构上返回 8。{wordsize, external}
- 返回模拟器的真实字大小,即指针的大小。该值以字节为单位,以整数形式给出。在纯 32 位架构上,返回 4。在 64 位架构上,返回 8。
-spec system_monitor() -> MonSettings when MonSettings :: undefined | {MonitorPid, Options}, MonitorPid :: pid(), Options :: [system_monitor_option()].
返回由 erlang:system_monitor/2
设置的当前系统监视设置,格式为 {MonitorPid, Options}
,如果不存在任何设置,则返回 undefined
。
选项的顺序可能与设置的顺序不同。
-spec system_monitor(Arg) -> MonSettings when Arg :: undefined | {MonitorPid, Options}, MonSettings :: undefined | {MonitorPid, Options}, MonitorPid :: pid(), Options :: [system_monitor_option()].
当使用参数 undefined
调用时,将清除所有系统性能监视设置。
使用 {MonitorPid, Options}
作为参数调用该函数与调用 erlang:system_monitor(MonitorPid, Options)
相同。
就像 erlang:system_monitor/0
一样,返回之前的系统监视器设置。
-spec system_monitor(MonitorPid, Options) -> MonSettings when MonitorPid :: pid(), Options :: [system_monitor_option()], MonSettings :: undefined | {OldMonitorPid, OldOptions}, OldMonitorPid :: pid(), OldOptions :: [system_monitor_option()].
设置系统性能监视选项。MonitorPid
是接收系统监视器消息的本地进程标识符(pid)。
第二个参数是一个监视选项列表
{long_gc, Time}
- 如果系统中的垃圾回收至少花费Time
毫秒的实际时间,则会向MonitorPid
发送消息{monitor, GcPid, long_gc, Info}
。GcPid
是被垃圾回收的进程 ID。Info
是一个由双元素元组组成的列表,描述垃圾回收的结果。其中一个元组是
{timeout, GcTime}
,其中GcTime
是垃圾回收的时间(以毫秒为单位)。其他元组标记有heap_size
、heap_block_size
、stack_size
、mbuf_size
、old_heap_size
和old_heap_block_size
。这些元组在跟踪消息gc_minor_start
的描述中进行了解释(请参阅trace:process/4
)。可以添加新的元组,并且Info
列表中元组的顺序可以随时更改,恕不另行通知。{long_message_queue, {Disable, Enable}}
- 如果系统中某个进程的消息队列长度达到Enable
长度,则会向MonitorPid
标识的进程发送一个long_message_queue
监视器消息。监视器消息的形式为{monitor, Pid, long_message_queue, Long}
,其中Pid
是消息队列过长的进程的进程标识符,Long
将等于true
,表示它处于长消息队列状态。由于Pid
标识的进程,在它的消息队列长度降至Disable
长度之前,不会发送更多long_message_queue
监视器消息。当这种情况发生时,将向MonitorPid
标识的进程发送一个Long
等于false
的long_message_queue
监视器消息,指示该进程不再处于长消息队列状态。因此,如果消息队列长度再次达到Enable
长度,将再次发送一个Long
设置为true
的新的long_message_queue
监视器消息。也就是说,当进程进入或离开长消息队列状态时,会发送long_message_queue
监视器消息,其中这些状态更改由Enable
和Disable
参数定义。Enable
长度必须是大于零的整数,Disable
长度必须是大于或等于零的整数。Disable
长度也必须小于Enable
长度。如果以上条件不满足,则操作将失败并抛出badarg
错误异常。建议对Disable
长度使用比Enable
长度小得多的值,以免被long_message_queue
监视器消息淹没。{long_schedule, Time}
- 如果系统中的进程或端口不中断地运行至少Time
毫秒的实际时间,则会向MonitorPid
发送消息{monitor, PidOrPort, long_schedule, Info}
。PidOrPort
是正在运行的进程或端口。Info
是一个由双元素元组组成的列表,描述该事件。如果为
pid/0
,则存在元组{timeout, Millis}
、{in, Location}
和{out, Location}
,其中Location
是描述进程被调度进入/退出的函数的 MFA ({Module, Function, Arity}
) 或原子undefined
。如果为
port/0
,则存在元组{timeout, Millis}
和{port_op,Op}
。Op
是proc_sig
、timeout
、input
、output
、event
或dist_cmd
之一,具体取决于正在执行的驱动程序回调。proc_sig
是一种内部操作,永远不会出现,而其他操作则代表相应的驱动程序回调timeout
、ready_input
、ready_output
、event
和outputv
(当端口用于分发时)。元组timeout
中的值Millis
提供有关进程或端口不中断的执行时间的信息,该时间始终等于或高于启动跟踪时提供的Time
值。可以在将来的版本中将新元组添加到Info
列表中。列表中元组的顺序可以随时更改,恕不另行通知。这可以用于检测 NIF 或驱动程序执行时间过长的问题。对于驱动程序回调或 NIF,1 毫秒被认为是良好的最大时间。但是,分时系统通常将所有 < 100 毫秒视为“可能”且相当“正常”。但是,较长的调度时间可能表示交换或 NIF/驱动程序行为不当。行为不当的 NIF 和驱动程序可能导致资源利用率不佳和整体系统性能不佳。
{large_heap, Size}
- 如果系统中的垃圾回收导致分配的堆大小至少为Size
个字,则会向MonitorPid
发送消息{monitor, GcPid, large_heap, Info}
。GcPid
和Info
与之前的long_gc
相同,只是缺少标记为timeout
的元组。如果垃圾回收后为所有堆世代分配的所有内存块的大小总和等于或高于
Size
,则会发送监视器消息。当进程被
max_heap_size
杀死时,它会在垃圾回收完成之前被杀死,因此不会发送大堆消息。busy_port
- 如果系统中的进程由于发送到繁忙的端口而被挂起,则会向MonitorPid
发送消息{monitor, SusPid, busy_port, Port}
。SusPid
是发送到Port
时被挂起的进程 ID。busy_dist_port
如果系统中的进程由于发送到远程节点上的进程而被挂起,该远程节点的节点间通信由繁忙的端口处理,则会向MonitorPid
发送消息{monitor, SusPid, busy_dist_port, Port}
。SusPid
是通过节点间通信端口Port
发送时被挂起的进程 ID。
就像 erlang:system_monitor/0
一样,返回之前的系统监视器设置。
system_monitor/2
的参数指定了节点上应如何完成所有系统监视,而不是应如何更改。这意味着一次只有一个进程(MonitorPid
)可以接收系统监视器消息。此外,清除特定监视器选项的方法是不将其包含在列表 Options
中。但是,如果 MonitorPid
标识的进程终止,则将清除所有系统监视。
没有特殊的选项值(如零)来清除选项。某些选项具有未指定的最小值。较低的值将调整为最小值。例如,目前无法使用 {long_gc, 0}
监视所有垃圾回收。
注意
如果监视进程变得太大,以至于它自己在垃圾回收时开始导致系统监视器消息,则这些消息会扩大进程消息队列,并且可能会使问题更加严重。
保持监视进程简洁,并且不要将系统监视器限制设置得太紧。
失败
badarg
- 如果MonitorPid
不存在。badarg
- 如果MonitorPid
不是本地进程。
-spec system_profile() -> ProfilerSettings when ProfilerSettings :: undefined | {ProfilerPid, Options}, ProfilerPid :: pid() | port(), Options :: [system_profile_option()].
返回由 erlang:system_profile/2
设置的当前系统分析设置,格式为 {ProfilerPid, Options}
,如果没有设置,则返回 undefined
。选项的顺序可能与设置的顺序不同。
-spec system_profile(ProfilerPid, Options) -> ProfilerSettings when ProfilerPid :: pid() | port() | undefined, Options :: [system_profile_option()], ProfilerSettings :: undefined | {pid() | port(), [system_profile_option()]}.
设置系统分析器选项。ProfilerPid
是接收分析消息的本地进程标识符(pid)或端口。接收者被排除在所有分析之外。第二个参数是一个分析选项列表。
exclusive
- 如果从进程同步调用端口,则在调用端口的运行时,调用进程被认为不可运行。当端口回调返回时,调用进程将收到inactive
通知,然后收到active
通知。monotonic_timestamp
- 性能分析消息中的时间戳使用Erlang 单调时间。时间戳 (Ts) 的格式和值与erlang:monotonic_time(nanosecond)
生成的相同。runnable_procs
- 如果进程被放入或从运行队列中移除,则会向ProfilerPid
发送消息{profile, Pid, State, Mfa, Ts}
。在被抢占后重新插入到运行队列中的正在运行的进程不会触发此消息。runnable_ports
- 如果端口被放入或从运行队列中移除,则会向ProfilerPid
发送消息{profile, Port, State, 0, Ts}
。scheduler
- 如果调度器进入睡眠或被唤醒,则会向ProfilerPid
发送消息{profile, scheduler, Id, State, NoScheds, Ts}
。strict_monotonic_timestamp
- 性能分析消息中的时间戳包括Erlang 单调时间和一个单调递增的整数。时间戳 (Ts) 的格式和值与{erlang:monotonic_time(nanosecond), erlang:unique_integer([monotonic])}
生成的相同。timestamp
- 性能分析消息中的时间戳包含一个时间戳 (Ts),其格式与erlang:now()
返回的格式相同。如果没有指定时间戳标志,这也是默认值。如果通过trace:process/4
启用了cpu_timestamp
,当启用标志timestamp
时,这也会影响性能分析消息中产生的时间戳。
注意
erlang:system_profile
的行为可能会在未来的版本中发生变化。
时间和定时器
-spec cancel_timer(TimerRef) -> Result when TimerRef :: reference(), Time :: non_neg_integer(), Result :: Time | false.
等效于 erlang:cancel_timer(TimerRef, [])
。
-spec cancel_timer(TimerRef, Options) -> Result | ok when TimerRef :: reference(), Async :: boolean(), Info :: boolean(), Option :: {async, Async} | {info, Info}, Options :: [Option], Time :: non_neg_integer(), Result :: Time | false.
取消由 erlang:start_timer
或 erlang:send_after
创建的计时器。TimerRef
标识该计时器,并且由创建该计时器的 BIF 返回。
Option
s
{async, Async}
- 异步取消请求。Async
默认为false
,这将导致同步执行取消操作。当Async
设置为true
时,将异步执行取消操作。也就是说,cancel_timer()
会向管理定时器的定时器服务发送异步取消请求,然后返回ok
。{info, Info}
- 请求有关取消Result
的信息。Info
默认为true
,这意味着将给出Result
。当Info
设置为false
时,不会给出关于取消结果的信息。- 当
Async
为false
时:如果Info
为true
,则Result
由erlang:cancel_timer()
返回。否则返回ok
。 - 当
Async
为true
时:如果Info
为true
,则当取消操作已执行时,将向erlang:cancel_timer()
的调用者发送格式为{cancel_timer, TimerRef, Result}
的消息,否则不发送任何消息。
- 当
将来可能会添加更多 Option
。
如果 Result
是一个整数,则表示取消的定时器到期之前剩余的时间(以毫秒为单位)。
如果 Result
为 false
,则表示找不到与 TimerRef
对应的定时器。这可能是因为定时器已过期、已被取消,或者因为 TimerRef
从未对应于任何定时器。即使定时器已过期,也无法知道超时消息是否已到达其目的地。
注意
管理定时器的定时器服务可能与调用进程正在执行的调度器位于不同的调度器上。如果是这样,与定时器服务的通信将比它位于本地需要更长的时间。如果调用进程位于关键路径中,并且可以在等待此操作结果的同时执行其他操作,或者对操作的结果不感兴趣,则应使用选项
{async, true}
。如果使用选项{async, false}
,则调用进程将阻塞,直到执行完该操作。
另请参阅 erlang:send_after/4
、erlang:start_timer/4
和 erlang:read_timer/2
。
-spec convert_time_unit(Time, FromUnit, ToUnit) -> ConvertedTime when Time :: integer(), ConvertedTime :: integer(), FromUnit :: time_unit(), ToUnit :: time_unit().
将时间单位为 FromUnit
的 Time
值转换为时间单位为 ToUnit
的相应 ConvertedTime
值。使用 floor/1
函数对结果进行舍入。
警告
在时间单位之间进行转换时,您可能会损失精度和准确性。为了最大限度地减少这种损失,请在
native
时间单位收集所有数据,并在最后结果上进行转换。
-spec date() -> Date when Date :: calendar:date().
以 {Year, Month, Day}
格式返回当前日期。
时区和夏令时校正取决于底层操作系统。返回值基于操作系统系统时间。
例如
> date().
{1995,2,19}
-spec localtime() -> DateTime when DateTime :: calendar:datetime().
返回当前的本地日期和时间,{{Year, Month, Day}, {Hour, Minute, Second}}
。
例如
> erlang:localtime().
{{1996,11,6},{14,45,17}}
时区和夏令时校正取决于底层操作系统。返回值基于操作系统系统时间。
-spec localtime_to_universaltime(Localtime) -> Universaltime when Localtime :: calendar:datetime(), Universaltime :: calendar:datetime().
如果底层操作系统支持,则将本地日期和时间转换为协调世界时 (UTC)。否则,不进行转换,并返回 Localtime
。
例如
> erlang:localtime_to_universaltime({{1996,11,6},{14,45,17}}).
{{1996,11,6},{13,45,17}}
失败:如果 Localtime
表示无效的日期和时间,则返回 badarg
。
-spec localtime_to_universaltime(Localtime, IsDst) -> Universaltime when Localtime :: calendar:datetime(), Universaltime :: calendar:datetime(), IsDst :: true | false | undefined.
与 erlang:localtime_to_universaltime/1
相同,将本地日期和时间转换为协调世界时 (UTC),但调用者决定是否启用夏令时。
如果 IsDst == true
,则 Localtime
在夏令时期间;如果 IsDst == false
,则不在夏令时期间。如果 IsDst == undefined
,则底层操作系统可以猜测,这与调用 erlang:localtime_to_universaltime(Localtime)
相同。
示例
> erlang:localtime_to_universaltime({{1996,11,6},{14,45,17}}, true).
{{1996,11,6},{12,45,17}}
> erlang:localtime_to_universaltime({{1996,11,6},{14,45,17}}, false).
{{1996,11,6},{13,45,17}}
> erlang:localtime_to_universaltime({{1996,11,6},{14,45,17}}, undefined).
{{1996,11,6},{13,45,17}}
失败:如果 Localtime
表示无效的日期和时间,则返回 badarg
。
-spec monotonic_time() -> integer().
以 native
时间单位 返回当前的 Erlang 单调时间。这是自某个未指定的时间点以来单调递增的时间。
注意
这是一个单调递增的时间,但不是一个严格单调递增的时间。也就是说,连续调用
erlang:monotonic_time/0
可能会产生相同的结果。不同的运行时系统实例将使用时间上不同的未指定点作为其 Erlang 单调时钟的基准。也就是说,比较来自不同运行时系统实例的单调时间是毫无意义的。不同的运行时系统实例也可以将此未指定的时间点放置在相对于运行时系统启动的不同位置。它可以放置在未来(启动时的时间为负值)、过去(启动时的时间为正值)或运行时系统启动时(启动时的时间为零)。可以通过调用
erlang:system_info(start_time)
来检索运行时系统启动时的单调时间。
返回转换为作为参数传递的 Unit
的当前 Erlang 单调时间。
与调用 erlang:convert_time_unit
(
erlang:monotonic_time()
, native, Unit)
相同,但是针对常用 Unit
进行了优化。
-spec read_timer(TimerRef) -> Result when TimerRef :: reference(), Time :: non_neg_integer(), Result :: Time | false.
等效于 erlang:read_timer(TimerRef, [])
。
-spec read_timer(TimerRef, Options) -> Result | ok when TimerRef :: reference(), Async :: boolean(), Option :: {async, Async}, Options :: [Option], Time :: non_neg_integer(), Result :: Time | false.
读取由 erlang:start_timer
或 erlang:send_after
创建的计时器的状态。TimerRef
标识该计时器,并且由创建该计时器的 BIF 返回。
选项
:
{async, Async}
- 异步请求状态信息。Async
默认为false
,这将导致同步执行操作。在这种情况下,Result
由erlang:read_timer
返回。当Async
为true
时,erlang:read_timer
会向管理定时器的定时器服务发送异步状态信息请求,然后返回ok
。当操作已处理时,将向erlang:read_timer
的调用者发送格式为{read_timer, TimerRef, Result}
的消息。
将来可能会添加更多 Option
。
如果 Result
是一个整数,则表示定时器到期之前剩余的时间(以毫秒为单位)。
如果 Result
为 false
,则表示找不到与 TimerRef
对应的定时器。这是因为定时器已过期或已被取消,或者因为 TimerRef
从未对应于任何定时器。即使定时器已过期,也无法知道超时消息是否已到达其目的地。
注意
管理定时器的定时器服务可能与调用进程正在执行的调度器位于不同的调度器上。如果是这样,与定时器服务的通信将比它位于本地需要更长的时间。如果调用进程位于关键路径中,并且可以在等待此操作结果的同时执行其他操作,则应使用选项
{async, true}
。如果使用选项{async, false}
,则调用进程将阻塞,直到执行完该操作。
另请参阅 erlang:send_after/4
、erlang:start_timer/4
和 erlang:cancel_timer/2
。
-spec send_after(Time, Dest, Msg) -> TimerRef when Time :: non_neg_integer(), Dest :: pid() | atom(), Msg :: term(), TimerRef :: reference().
等效于 erlang:send_after(Time, Dest, Msg, [])
。
-spec send_after(Time, Dest, Msg, Options) -> TimerRef when Time :: integer(), Dest :: pid() | atom(), Msg :: term(), Options :: [Option], Abs :: boolean(), Option :: {abs, Abs}, TimerRef :: reference().
启动计时器。当计时器到期时,消息 Msg
将发送到由 Dest
标识的进程。除了超时消息的格式之外,此函数的工作方式与 erlang:start_timer/4
完全相同。
-spec start_timer(Time, Dest, Msg) -> TimerRef when Time :: non_neg_integer(), Dest :: pid() | atom(), Msg :: term(), TimerRef :: reference().
等效于 erlang:start_timer(Time, Dest, Msg, [])
。
-spec start_timer(Time, Dest, Msg, Options) -> TimerRef when Time :: integer(), Dest :: pid() | atom(), Msg :: term(), Options :: [Option], Abs :: boolean(), Option :: {abs, Abs}, TimerRef :: reference().
启动计时器。当计时器到期时,消息 {timeout, TimerRef, Msg}
将发送到由 Dest
标识的进程。
Option
s
{abs, false}
- 这是默认值。它表示Time
值被解释为相对于当前 Erlang 单调时间的毫秒数相对时间。{abs, true}
- 绝对Time
值。Time
值被解释为绝对 Erlang 单调时间,单位为毫秒。
将来可能会添加更多 Option
。
定时器被设置为过期的时间点必须在区间 [
erlang:convert_time_unit(
erlang:system_info(start_time), native, millisecond),
erlang:convert_time_unit(
erlang:system_info(end_time), native, millisecond) ]
内。如果指定的是相对时间,则 Time
值不允许为负数。
如果 Dest
是一个 pid/0
,它必须是当前运行时系统实例上创建的进程的 pid/0
。此进程可能已经终止或尚未终止。如果 Dest
是一个 atom/0
,它将被解释为本地注册进程的名称。该名称所引用的进程将在定时器过期时查找。如果该名称没有引用任何进程,则不会返回错误。
如果 Dest
是一个 pid/0
,如果 pid/0
引用的进程未存活,或者进程退出,则定时器将自动取消。此功能是在 ERTS 5.4.11 中引入的。请注意,当 Dest
是一个 atom/0
时,定时器不会自动取消。
另请参阅 erlang:send_after/4
,erlang:cancel_timer/2
和 erlang:read_timer/2
。
有关 Erlang 中定时器的一般信息,请参阅 定时器 部分,该部分位于 Erlang 中的时间和时间校正 ERTS 用户指南中。
失败:如果参数不满足此处指定的要求,则返回 badarg
。
-spec system_time() -> integer().
以 native
时间单位 返回当前的 Erlang 系统时间。
调用 erlang:system_time()
等效于 erlang:monotonic_time()
+
erlang:time_offset()
。
注意
在一般情况下,此时间不是单调递增的时间。有关更多信息,请参阅用户指南中关于 时间扭曲模式的文档。
返回转换为作为参数传递的 Unit
的当前 Erlang 系统时间。
调用 erlang:system_time(Unit)
等效于 erlang:convert_time_unit
(
erlang:system_time()
, native, Unit)
。
注意
在一般情况下,此时间不是单调递增的时间。有关更多信息,请参阅用户指南中关于 时间扭曲模式的文档。
-spec time() -> Time when Time :: calendar:time().
以 {Hour, Minute, Second}
格式返回当前时间。
时区和夏令时校正取决于底层操作系统。返回值基于操作系统系统时间。
例如
> time().
{9,42,44}
-spec time_offset() -> integer().
以 native
时间单位 返回 Erlang 单调时间 和 Erlang 系统时间 之间的当前时间偏移量。将当前时间偏移量添加到 Erlang 单调时间即可得到相应的 Erlang 系统时间。
时间偏移可能会在操作期间更改,也可能不会更改,具体取决于所使用的 时间扭曲模式。
注意
不同的进程可能会在略有不同的时间点观察到时间偏移的变化。
如果运行时系统处于 多时间扭曲模式,则当运行时系统检测到 操作系统系统时间已更改时,时间偏移会发生变化。但是,运行时系统不会立即检测到此更改。检查时间偏移的任务被安排为至少每分钟执行一次;因此,在正常操作下,这将在 1 分钟内被检测到,但在高负载期间,可能需要更长的时间。
返回 Erlang 单调时间 和 Erlang 系统时间 之间当前的时间偏移量,并转换为作为参数传递的 Unit
单位。
与调用 erlang:convert_time_unit
(
erlang:time_offset()
, native, Unit)
相同,但针对常用的 Unit
进行了优化。
-spec timestamp() -> Timestamp when Timestamp :: timestamp().
以 {MegaSecs, Secs, MicroSecs}
格式返回当前的 Erlang 系统时间。
此格式与 os:timestamp/0
和已弃用的 erlang:now/0
使用的格式相同。erlang:timestamp()
存在的原因纯粹是为了简化现有代码的使用,这些代码假设此时间戳格式。可以使用 erlang:system_time/1
以您选择的时间单位更有效地检索当前 Erlang 系统时间。
erlang:timestamp()
BIF 等效于
timestamp() ->
ErlangSystemTime = erlang:system_time(microsecond),
MegaSecs = ErlangSystemTime div 1000_000_000_000,
Secs = ErlangSystemTime div 1000_000 - MegaSecs*1000_000,
MicroSecs = ErlangSystemTime rem 1000_000,
{MegaSecs, Secs, MicroSecs}.
但是,它使用不会在堆上构建垃圾且性能略好的本机实现。
注意
在一般情况下,此时间不是单调递增的时间。有关更多信息,请参阅用户指南中关于 时间扭曲模式的文档。
-spec universaltime() -> DateTime when DateTime :: calendar:datetime().
如果底层操作系统支持,则以 {{Year, Month, Day}, {Hour, Minute, Second}}
形式返回协调世界时 (UTC) 的当前日期和时间。否则,erlang:universaltime()
等同于 erlang:localtime()
。返回值基于 操作系统系统时间。
例如
> erlang:universaltime().
{{1996,11,6},{14,18,43}}
-spec universaltime_to_localtime(Universaltime) -> Localtime when Localtime :: calendar:datetime(), Universaltime :: calendar:datetime().
如果底层操作系统支持,则将协调世界时 (UTC) 日期和时间转换为本地日期和时间,格式为 {{Year, Month, Day}, {Hour, Minute, Second}}
。否则,不进行转换,并返回 Universaltime
。
例如
> erlang:universaltime_to_localtime({{1996,11,6},{14,18,43}}).
{{1996,11,7},{15,18,43}}
失败:如果 Universaltime
表示无效的日期和时间,则返回 badarg
。
跟踪
-spec trace(PidPortSpec, How, FlagList) -> integer() when PidPortSpec :: pid() | port() | all | processes | ports | existing | existing_processes | existing_ports | new | new_processes | new_ports, How :: boolean(), FlagList :: [trace_flag()].
为静态传统跟踪会话打开或关闭进程或端口的跟踪标志。
变更
此函数已被对动态跟踪会话进行操作的
trace:process/4
和trace:port/4
取代。
参数 FlagList
可以包含两个额外的选项
{tracer, Tracer}
- 指定将跟踪消息发送到哪里。Tracer
必须是本地进程的进程标识符或本地端口的端口标识符。{tracer, TracerModule, TracerState}
- 指定调用跟踪器模块而不是发送跟踪消息。然后,跟踪器模块可以忽略或更改跟踪消息。有关如何编写跟踪器模块的更多详细信息,请参阅erl_tracer
。
如果未指定 tracer
,则调用进程将接收所有跟踪消息。传统跟踪会话没有指定的跟踪器。
有关更多文档,请参阅 trace:process/4
和 trace:port/4
。
调用此函数确保所有跟踪消息都已传递。
跟踪消息的传递(由 erlang:trace/3
,seq_trace
或 erlang:system_profile/2
生成)与系统中其他事件相比,在时间线上是错位的。如果您知道 Tracee
已通过其执行中的某个特定点,并且您想知道何时至少所有与该点之前的事件对应的跟踪消息已到达跟踪器,请使用 erlang:trace_delivered(Tracee)
。
当保证所有跟踪消息都已传递到跟踪器时,直到 Tracee
在调用 erlang:trace_delivered(Tracee)
时到达的那个点,然后会向 erlang:trace_delivered(Tracee)
的调用者发送一个 {trace_delivered, Tracee, Ref}
消息。
请注意,消息 trace_delivered
并不意味着跟踪消息已被传递。相反,它意味着所有要传递的跟踪消息都已传递。如果 Tracee
没有,并且没有被任何人跟踪,则这不是错误,但是如果出现这种情况,则当 trace_delivered
消息到达时,没有跟踪消息被传递。
请注意,Tracee
必须引用当前或以前存在于与 erlang:trace_delivered(Tracee)
的调用者所在的同一节点上的进程。特殊的 Tracee
原子 all
表示当前在节点中被跟踪的所有进程。
当与 Tracer Module 一起使用时,保证在发送 trace_delivered
消息之前,跟踪回调中发送的任何消息都已到达其接收者。
示例:进程 A
是 Tracee
,端口 B
是跟踪器,进程 C
是 B
的端口所有者。C
希望在 A
退出时关闭 B
。为确保跟踪不会被截断,C
可以在 A
退出时调用 erlang:trace_delivered(A)
,并在关闭 B
之前等待消息 {trace_delivered, A, Ref}
。
失败:如果 Tracee
没有引用与 erlang:trace_delivered(Tracee)
的调用者所在的同一节点上的进程(死或活),则返回 badarg
。
-spec trace_info(PidPortFuncEvent, Item) -> Res when PidPortFuncEvent :: pid() | port() | new | new_processes | new_ports | {Module, Function, Arity} | on_load | send | 'receive', Module :: module(), Function :: atom(), Arity :: arity(), Item :: flags | tracer | traced | match_spec | meta | meta_match_spec | call_count | call_time | call_memory | all, Res :: trace_info_return().
为静态传统跟踪会话返回有关端口、进程、函数或事件的跟踪信息。
变更
此函数已被对动态跟踪会话进行操作的
trace:info/3
取代。
-spec trace_pattern(MFA, MatchSpec) -> non_neg_integer() when MFA :: trace_pattern_mfa() | send | 'receive', MatchSpec :: (MatchSpecList :: trace_match_spec()) | boolean() | restart | pause.
等同于 erlang:trace_pattern(Event, MatchSpec, [])
,保留以实现向后兼容性。
-spec trace_pattern(send, MatchSpec, []) -> non_neg_integer() when MatchSpec :: (MatchSpecList :: trace_match_spec()) | boolean(); ('receive', MatchSpec, []) -> non_neg_integer() when MatchSpec :: (MatchSpecList :: trace_match_spec()) | boolean(); (MFA, MatchSpec, FlagList) -> non_neg_integer() when MFA :: trace_pattern_mfa(), MatchSpec :: (MatchSpecList :: trace_match_spec()) | boolean() | restart | pause, FlagList :: [trace_pattern_flag()].
为静态传统跟踪会话设置调用、发送和接收跟踪的跟踪模式。
变更
此函数已被对动态跟踪会话进行操作的
trace:function/4
,trace:send/3
和trace:recv/3
取代。
参数 FlagList
可以包含用于调用跟踪的两个附加选项
{meta, Pid} | {meta, TracerModule, TracerState}
- 为所有类型的函数调用打开或关闭元跟踪。每当调用任何指定的函数时,都会将跟踪消息发送到跟踪器。如果未指定跟踪器,则使用self/0
作为默认跟踪器进程。
更多文档请参阅 trace:function/4
、trace:send/3
和 trace:recv/3
。
已弃用的函数
-spec now() -> Timestamp when Timestamp :: timestamp().
警告
此函数已弃用。请勿使用它。
有关更多信息,请参阅用户指南中的 时间和时间校正 部分。 具体来说,注意事项 部分描述了应该使用什么来代替
erlang:now/0
。
返回元组 {MegaSecs, Secs, MicroSecs}
,它是自 1970 年 1 月 1 日格林威治标准时间 00:00(零时)以来经过的时间(如果底层操作系统提供)。 否则,将选择其他某个时间点。 此外,还保证对此 BIF 的后续调用返回连续递增的值。 因此,erlang:now/0
的返回值可用于生成唯一的时间戳。 如果在快速机器上的紧密循环中调用它,则节点的时间可能会发生偏差。
只有在正确配置了底层操作系统的时区信息后,才能用于检查当地时间。
-spec phash(Term, Range) -> Hash when Term :: term(), Range :: pos_integer(), Hash :: pos_integer().
警告
此函数已弃用,因为新代码应使用
erlang:phash2/2
。请注意,erlang:phash(X,N)
不一定等于erlang:phash2(X,N)
可移植哈希函数,对于相同的 Erlang 项,无论机器架构和 ERTS 版本如何,都给出相同的哈希值(此 BIF 在 ERTS 4.9.1.1 中引入)。 该函数返回 Term
在 1..Range
范围内的哈希值。Range
的最大值为 2^32。