查看源代码 proc_lib (stdlib v6.2)

用于异步和同步启动符合 OTP 设计原则的进程的函数。

此模块用于启动符合 OTP 设计原则的进程。具体来说,此模块中的函数由 OTP 标准行为(例如,gen_servergen_statem)在启动新进程时使用。这些函数还可以用于启动特殊进程,即符合 OTP 设计原则的用户定义进程。有关示例,请参见 OTP 设计原则中的 sys 和 proc_lib 部分。

当进程启动时,会初始化一些有用的信息。父进程的注册名称或进程标识符以及父进程的祖先都与进程中最初调用的函数的信息一起存储。

在“纯 Erlang”中,只有当退出原因是 normal 时,进程才被认为正常终止,而使用 proc_lib 启动的进程,如果退出原因是 shutdown{shutdown,Term},也被认为正常终止。shutdown 是在应用程序(监管树)停止时使用的原因。

当使用 proc_lib 启动的进程异常终止时(即,退出原因不是 normalshutdown{shutdown,Term}),会生成一个崩溃报告,该报告由内核设置的默认日志处理程序写入终端。有关在 Erlang/OTP 21.0 之前如何记录崩溃报告的更多信息,请参阅 SASL 用户指南中的SASL 错误日志记录

与“纯 Erlang”不同,proc_lib 进程不会生成错误报告,这些报告由模拟器写入终端。所有异常都转换为退出,默认的 logger 处理程序会忽略这些退出。

崩溃报告包含先前存储的信息,例如祖先和初始函数、终止原因以及有关其他因该进程终止而终止的进程的信息。

另请参阅

logger

概述

类型

传递给 init_fail/3 的异常。 有关 ClassReasonStacktrace 的说明,请参阅 erlang:raise/3

spawn 选项的受限集合。 最值得注意的是,monitor 不是这些选项的一部分。

函数

注意

此函数已被弃用,因为 error_logger 不再是 Erlang/OTP 中首选的日志记录接口。Erlang/OTP 21.0 中添加了一个新的 日志记录 API,但仍然可以使用旧的 error_logger 处理程序。新的 Logger 处理程序不需要使用此函数,因为格式化回调 (report_cb) 包含在日志事件的元数据中。

注意

此函数已被弃用,因为 error_logger 不再是 Erlang/OTP 中首选的日志记录接口。Erlang/OTP 21.0 中添加了一个新的 日志记录 API,但仍然可以使用旧的 error_logger 处理程序。新的 Logger 处理程序不需要使用此函数,因为格式化回调 (report_cb) 包含在日志事件的元数据中。

返回 undefined 或使用 proc_lib:set_label/1 为进程 Pid 设置的标签。

此函数与 hibernate/3 BIF 执行相同的操作(并调用该 BIF),但确保当进程唤醒时,异常处理和日志记录继续按预期工作。

等效于 init_ack(Parent, Ret),其中 Parent 是调用 start/5 的进程。

此函数只能由通过 start[_link|_monitor]/3,4,5 函数启动的进程使用。它告诉 Parent 进程已初始化自身并已启动。

等效于 init_fail(Parent, Return, Exception),其中 Parent 是调用 start/5 的进程。

此函数只能由通过 start[_link|_monitor]/3,4,5 函数启动的进程使用。它告诉 Parent 进程初始化失败,并根据 Exception 立即引发异常。然后,启动函数返回 Ret

提取使用此模块中的 spawn 或 start 函数之一启动的进程的初始调用。Process 可以是 pid、整数元组(可以从中创建 pid)或通过 erlang:process_info(Pid) 函数调用获取的进程 Pid 的进程信息。

为当前进程设置标签。主要目的是帮助调试未注册的进程。进程标签可以在工具和崩溃报告中用于标识进程,但它不必像注册名称那样是唯一的或原子。进程标签可以是任何项,例如 {worker_process, 1..N}

生成一个新进程,并按照本手册页开头所述对其进行初始化。使用 spawn BIF 生成进程。

生成一个新进程,并按照本手册页开头所述对其进行初始化。使用 spawn_link BIF 生成进程。

生成一个新进程,并按照本手册页开头所述对其进行初始化。使用 erlang:spawn_opt BIF 生成进程。

同步启动新进程。生成进程并等待其启动。

同步启动新进程。生成进程并等待其启动。原子地在新生成的进程上设置链接。

同步启动新进程。生成进程并等待其启动。原子地在新生成的进程上设置监视器。

命令进程以指定的 Reason 退出,并等待其终止。

函数 c:i/0c:regs/0 使用此函数来呈现进程信息。

类型

链接到此类型

dict_or_pid()

查看源代码 (未导出)
-type dict_or_pid() :: pid() | (ProcInfo :: [_]) | {X :: integer(), Y :: integer(), Z :: integer()}.
-type exception() ::
          {Class :: error | exit | throw, Reason :: term()} |
          {Class :: error | exit | throw, Reason :: term(), Stacktrace :: erlang:raise_stacktrace()}.

传递给 init_fail/3 的异常。 有关 ClassReasonStacktrace 的说明,请参阅 erlang:raise/3

-type spawn_option() :: erlang:spawn_opt_option().

等效于 erlang:spawn_opt_option/0

-type start_spawn_option() ::
          link |
          {priority, erlang:priority_level()} |
          {fullsweep_after, non_neg_integer()} |
          {min_heap_size, non_neg_integer()} |
          {min_bin_vheap_size, non_neg_integer()} |
          {max_heap_size, erlang:max_heap_size()} |
          {message_queue_data, erlang:message_queue_data()}.

spawn 选项的受限集合。 最值得注意的是,monitor 不是这些选项的一部分。

函数

-spec format(CrashReport) -> string() when CrashReport :: [term()].

等效于 format(CrashReport, latin1)

链接到此函数

format(CrashReport, Encoding)

查看源代码 (自 OTP R16B 起)
-spec format(CrashReport, Encoding) -> string()
                when CrashReport :: [term()], Encoding :: latin1 | unicode | utf8.

注意

此函数已被弃用,因为 error_logger 不再是 Erlang/OTP 中首选的日志记录接口。Erlang/OTP 21.0 中添加了一个新的 日志记录 API,但仍然可以使用旧的 error_logger 处理程序。新的 Logger 处理程序不需要使用此函数,因为格式化回调 (report_cb) 包含在日志事件的元数据中。

用户自定义的旧版 error_logger 事件处理程序可以使用此函数来格式化崩溃报告。崩溃报告通过 logger 发送,要处理的事件格式为 {error_report, GL, {Pid, crash_report, CrashReport}},其中 GL 是发送崩溃报告的进程 Pid 的组领导者 pid。

链接到此函数

format(CrashReport, Encoding, Depth)

查看源代码 (自 OTP 18.1 起)
-spec format(CrashReport, Encoding, Depth) -> string()
                when
                    CrashReport :: [term()],
                    Encoding :: latin1 | unicode | utf8,
                    Depth :: unlimited | pos_integer().

注意

此函数已被弃用,因为 error_logger 不再是 Erlang/OTP 中首选的日志记录接口。Erlang/OTP 21.0 中添加了一个新的 日志记录 API,但仍然可以使用旧的 error_logger 处理程序。新的 Logger 处理程序不需要使用此函数,因为格式化回调 (report_cb) 包含在日志事件的元数据中。

用户自定义的旧版 error_logger 事件处理程序可以使用此函数来格式化崩溃报告。当 Depth 指定为正整数时,它将在格式字符串中使用,以限制输出,如下所示:io_lib:format("~P", [Term,Depth])

链接到此函数

get_label(Pid)

查看源代码 (自 OTP 27.0 起)
-spec get_label(Pid) -> undefined | term() when Pid :: pid().

返回 undefined 或使用 proc_lib:set_label/1 为进程 Pid 设置的标签。

链接到此函数

hibernate(Module, Function, Args)

查看源代码
-spec hibernate(Module, Function, Args) -> no_return()
                   when Module :: module(), Function :: atom(), Args :: [term()].

此函数与 hibernate/3 BIF 执行相同的操作(并调用该 BIF),但确保当进程唤醒时,异常处理和日志记录继续按预期工作。

对于使用 proc_lib 函数启动的进程,请始终使用此函数,而不是 BIF。

-spec init_ack(Ret) -> ok when Ret :: term().

等效于 init_ack(Parent, Ret),其中 Parent 是调用 start/5 的进程。

-spec init_ack(Parent, Ret) -> ok when Parent :: pid(), Ret :: term().

此函数只能由通过 start[_link|_monitor]/3,4,5 函数启动的进程使用。它告诉 Parent 进程已初始化自身并已启动。

函数 init_ack/1 使用先前由启动函数存储的父值。

如果启动的进程既没有调用此函数,也没有调用 init_fail/2,3,则当启动的进程退出时,或当启动函数超时(如果使用)时,启动函数会返回一个错误元组,请参见 start/3,4,5

警告

不要使用此函数返回指示进程启动失败的错误。这样做时,启动函数可以在失败的进程退出之前返回,这可能会阻塞新的启动尝试成功所需的 VM 资源。为此,请使用 init_fail/2,3

以下示例说明了如何使用此函数和 proc_lib:start_link/3

-module(my_proc).
-export([start_link/0]).
-export([init/1]).

start_link() ->
    proc_lib:start_link(my_proc, init, [self()]).

init(Parent) ->
    case do_initialization() of
        ok ->
            proc_lib:init_ack(Parent, {ok, self()});
        {error, Reason} ->
            exit(Reason)
    end,
    loop().

...
链接到此函数

init_fail(Return, Exception)

查看源代码 (自 OTP 26.0 起)
-spec init_fail(Return :: term(), Exception :: exception()) -> no_return().

等效于 init_fail(Parent, Return, Exception),其中 Parent 是调用 start/5 的进程。

链接到此函数

init_fail(Parent, Return, Exception)

查看源代码 (自 OTP 26.0 起)
-spec init_fail(Parent :: pid(), Return :: term(), Exception :: exception()) -> no_return().

此函数只能由通过 start[_link|_monitor]/3,4,5 函数启动的进程使用。它告诉 Parent 进程初始化失败,并根据 Exception 立即引发异常。然后,启动函数返回 Ret

有关 ClassReasonStacktrace 的描述,请参见 erlang:raise/3

警告

不要考虑捕获此函数中的异常。这会破坏其目的。start[_link|_monitor]/3,4,5 函数启动的进程应以值(将被忽略)或将由此模块处理的异常结束。请参阅 描述

如果启动的进程既没有调用此函数,也没有调用 init_ack/1,2,则当启动的进程退出时,或当启动函数超时(如果使用)时,启动函数会返回一个错误元组,请参见 start/3,4,5

以下示例说明了如何使用此函数和 proc_lib:start_link/3

-module(my_proc).
-export([start_link/0]).
-export([init/1]).

start_link() ->
    proc_lib:start_link(my_proc, init, [self()]).

init(Parent) ->
    case do_initialization() of
        ok ->
            proc_lib:init_ack(Parent, {ok, self()});
        {error, Reason} = Error ->
            proc_lib:init_fail(Parent, Error, {exit, normal})
    end,
    loop().

...
-spec initial_call(Process) -> {Module, Function, Args} | false
                      when
                          Process :: dict_or_pid(),
                          Module :: module(),
                          Function :: atom(),
                          Args :: [atom()].

提取使用此模块中的 spawn 或 start 函数之一启动的进程的初始调用。Process 可以是 pid、整数元组(可以从中创建 pid)或通过 erlang:process_info(Pid) 函数调用获取的进程 Pid 的进程信息。

注意

列表 Args 不再包含参数,而是包含与参数数量相同的原子数量;第一个原子是 'Argument__1',第二个是 'Argument__2',依此类推。原因是参数列表可能会浪费大量内存,并且如果参数列表包含 fun,则可能无法升级该模块的代码。

如果进程是使用 fun 生成的,则 initial_call/1 不再返回 fun,而是返回模块、实现 fun 的本地函数的函数和元数,例如,{some_module,-work/3-fun-0-,0}(表示 fun 是在函数 some_module:work/3 中创建的)。原因是保留 fun 会阻止模块的代码升级,并且可能会浪费大量内存。

链接到此函数

set_label(Label)

查看源代码 (自 OTP 27.0 起)
-spec set_label(Label) -> ok when Label :: term().

为当前进程设置标签。主要目的是帮助调试未注册的进程。进程标签可以在工具和崩溃报告中用于标识进程,但它不必像注册名称那样是唯一的或原子。进程标签可以是任何项,例如 {worker_process, 1..N}

使用 proc_lib:get_label/1 来查找进程描述。

-spec spawn(Fun) -> pid() when Fun :: function().

等效于 spawn(erlang, apply, [Fun])

-spec spawn(Node, Fun) -> pid() when Node :: node(), Fun :: function().

等效于 spawn(Node, apply, erlang, [Fun])

链接到此函数

spawn(Module, Function, Args)

查看源代码
-spec spawn(Module, Function, Args) -> pid()
               when Module :: module(), Function :: atom(), Args :: [term()].

等效于 spawn(node(), Module, Function, Args)

链接到此函数

spawn(Node, Module, Function, Args)

查看源代码
-spec spawn(Node, Module, Function, Args) -> pid()
               when Node :: node(), Module :: module(), Function :: atom(), Args :: [term()].

生成一个新进程,并按照本手册页开头所述对其进行初始化。使用 spawn BIF 生成进程。

-spec spawn_link(Fun) -> pid() when Fun :: function().

等效于 spawn_link(erlang, apply, [Fun])

-spec spawn_link(Node, Fun) -> pid() when Node :: node(), Fun :: function().

等效于 spawn_link(Node, erlang, apply, [Fun])

链接到此函数

spawn_link(Module, Function, Args)

查看源代码
-spec spawn_link(Module, Function, Args) -> pid()
                    when Module :: module(), Function :: atom(), Args :: [term()].

等效于 spawn_link(node(), Module, Function, Args)

链接到此函数

spawn_link(Node, Module, Function, Args)

查看源代码
-spec spawn_link(Node, Module, Function, Args) -> pid()
                    when Node :: node(), Module :: module(), Function :: atom(), Args :: [term()].

生成一个新进程,并按照本手册页开头所述对其进行初始化。使用 spawn_link BIF 生成进程。

链接到此函数

spawn_opt(Fun, SpawnOpts)

查看源代码
-spec spawn_opt(Fun, SpawnOpts) -> pid() | {pid(), reference()}
                   when Fun :: function(), SpawnOpts :: [erlang:spawn_opt_option()].

等效于 spawn_opt(erlang, apply, [Fun], SpawnOpts)

链接到此函数

spawn_opt(Node, Fun, SpawnOpts)

查看源代码
-spec spawn_opt(Node, Fun, SpawnOpts) -> pid() | {pid(), reference()}
                   when Node :: node(), Fun :: function(), SpawnOpts :: [erlang:spawn_opt_option()].

等效于 spawn_opt(Node, erlang, apply, [Fun], SpawnOpts)

链接到此函数

spawn_opt(Module, Function, Args, SpawnOpts)

查看源代码
-spec spawn_opt(Module, Function, Args, SpawnOpts) -> pid() | {pid(), reference()}
                   when
                       Module :: module(),
                       Function :: atom(),
                       Args :: [term()],
                       SpawnOpts :: [erlang:spawn_opt_option()].

等效于 spawn_opt(node(), Module, Function, Args, SpawnOpts)

链接到此函数

spawn_opt(Node, Module, Function, Args, SpawnOpts)

查看源代码
-spec spawn_opt(Node, Module, Function, Args, SpawnOpts) -> pid() | {pid(), reference()}
                   when
                       Node :: node(),
                       Module :: module(),
                       Function :: atom(),
                       Args :: [term()],
                       SpawnOpts :: [erlang:spawn_opt_option()].

生成一个新进程,并按照本手册页开头所述对其进行初始化。使用 erlang:spawn_opt BIF 生成进程。

链接到此函数

start(Module, Function, Args)

查看源代码
-spec start(Module, Function, Args) -> Ret
               when
                   Module :: module(),
                   Function :: atom(),
                   Args :: [term()],
                   Ret :: term() | {error, Reason :: term()}.

等效于 start(Module, Function, Args, infinity)

链接到此函数

start(Module, Function, Args, Time)

查看源代码
-spec start(Module, Function, Args, Time) -> Ret
               when
                   Module :: module(),
                   Function :: atom(),
                   Args :: [term()],
                   Time :: timeout(),
                   Ret :: term() | {error, Reason :: term()}.

等效于 start(Module, Function, Args, Time, [])

链接到此函数

start(Module, Function, Args, Time, SpawnOpts)

查看源代码
-spec start(Module, Function, Args, Time, SpawnOpts) -> Ret
               when
                   Module :: module(),
                   Function :: atom(),
                   Args :: [term()],
                   Time :: timeout(),
                   SpawnOpts :: [start_spawn_option()],
                   Ret :: term() | {error, Reason :: term()}.

同步启动新进程。生成进程并等待其启动。

要指示启动成功,启动的进程必须调用 init_ack(Parent, Ret),其中 Parent 是计算此函数的进程,或者调用 init_ack(Ret)Ret 然后由此函数返回。

如果进程启动失败,它必须失败;最好通过调用 init_fail(Parent, Ret, Exception) ,其中 Parent 是计算此函数的进程,或者调用 init_fail(Ret, Exception)Ret 然后由此函数返回,并且启动的进程将以 Exception 失败。

如果进程在调用 init_ack/1,2init_fail/2,3 之前失败,则此函数返回 {error, Reason},其中 Reason 与进程链接 {'EXIT',Pid,Reason} 消息的异常有点相似。

如果 Time 指定为整数,则此函数将等待 Time 毫秒,以便新进程调用 init_ack/1,2init_fail/2,3,否则该进程将被终止,并且返回 Ret = {error, timeout}

如果指定了参数 SpawnOpts,则将其作为最后一个参数传递给 spawn_opt/4 BIF。

注意

不允许使用生成选项 monitor。这会导致函数因 badarg 原因而失败。

使用生成选项 link 将会为生成的进程设置一个链接,就像 start_link/3,4,5 一样。

链接到此函数

start_link(Module, Function, Args)

查看源代码
-spec start_link(Module, Function, Args) -> Ret
                    when
                        Module :: module(),
                        Function :: atom(),
                        Args :: [term()],
                        Ret :: term() | {error, Reason :: term()}.

等效于 start_link(Module, Function, Args, infinity)

链接到此函数

start_link(Module, Function, Args, Time)

查看源代码
-spec start_link(Module, Function, Args, Time) -> Ret
                    when
                        Module :: module(),
                        Function :: atom(),
                        Args :: [term()],
                        Time :: timeout(),
                        Ret :: term() | {error, Reason :: term()}.

等效于 start_link(Module, Function, Args, Time, [])

链接到此函数

start_link(Module, Function, Args, Time, SpawnOpts)

查看源代码
-spec start_link(Module, Function, Args, Time, SpawnOpts) -> Ret
                    when
                        Module :: module(),
                        Function :: atom(),
                        Args :: [term()],
                        Time :: timeout(),
                        SpawnOpts :: [start_spawn_option()],
                        Ret :: term() | {error, Reason :: term()}.

同步启动新进程。生成进程并等待其启动。原子地在新生成的进程上设置链接。

注意

如果启动的进程被终止或因非 normal 的原因崩溃,则进程链接将终止调用进程,因此除非调用进程捕获退出,否则此函数不会返回。例如,如果此函数超时,它将终止生成的进程,然后该链接可能会终止调用进程。

除了在生成的进程上设置链接之外,此函数的行为类似于 start/5

当调用进程捕获退出时;如果此函数由于生成的进程退出(任何错误返回)而返回,则此函数会接收(消耗)'EXIT' 消息,即使此函数超时并终止生成的进程时也是如此。

注意

不允许使用生成选项 monitor。这会导致函数因 badarg 原因而失败。

链接到此函数

start_monitor(Module, Function, Args)

查看源代码 (自 OTP 23.0 起)
-spec start_monitor(Module, Function, Args) -> {Ret, Mon}
                       when
                           Module :: module(),
                           Function :: atom(),
                           Args :: [term()],
                           Mon :: reference(),
                           Ret :: term() | {error, Reason :: term()}.

等效于 start_monitor(Module, Function, Args, infinity)

链接到此函数

start_monitor(Module, Function, Args, Time)

查看源代码 (自 OTP 23.0 起)
-spec start_monitor(Module, Function, Args, Time) -> {Ret, Mon}
                       when
                           Module :: module(),
                           Function :: atom(),
                           Args :: [term()],
                           Time :: timeout(),
                           Mon :: reference(),
                           Ret :: term() | {error, Reason :: term()}.

等效于 start_monitor(Module, Function, Args, Time, [])

链接到此函数

start_monitor(Module, Function, Args, Time, SpawnOpts)

查看源代码 (自 OTP 23.0 起)
-spec start_monitor(Module, Function, Args, Time, SpawnOpts) -> {Ret, Mon}
                       when
                           Module :: module(),
                           Function :: atom(),
                           Args :: [term()],
                           Time :: timeout(),
                           SpawnOpts :: [start_spawn_option()],
                           Mon :: reference(),
                           Ret :: term() | {error, Reason :: term()}.

同步启动新进程。生成进程并等待其启动。原子地在新生成的进程上设置监视器。

除了在生成的进程上设置监视器之外,此函数的行为类似于 start/5

返回值是 {Ret, Mon},其中 Ret 对应于对 init_ack/1,2init_fail/2,3 的调用中的 Ret 参数,而 Mon 是已设置的监视器的监视器引用。

如果此函数由于生成的进程退出而返回(即返回任何错误值),则将向调用进程传递 'DOWN' 消息,即使此函数超时并终止生成的进程时也是如此。

注意

不允许使用生成选项 monitor。这会导致函数因 badarg 原因而失败。

使用生成选项 link 将会为生成的进程设置一个链接,就像 start_link/3,4,5 一样。

链接到此函数

stop(Process)

查看源代码 (自 OTP 18.0 起)
-spec stop(Process) -> ok when Process :: pid() | RegName | {RegName, node()}, RegName :: atom().

等效于 stop(Process, normal, infinity)

链接到此函数

stop(Process, Reason, Timeout)

查看源代码 (自 OTP 18.0 起)
-spec stop(Process, Reason, Timeout) -> ok
              when
                  Process :: pid() | RegName | {RegName, node()},
                  RegName :: atom(),
                  Reason :: term(),
                  Timeout :: timeout().

命令进程以指定的 Reason 退出,并等待其终止。

如果进程在 Timeout 毫秒内以指定的 Reason 退出,则返回 ok

如果调用超时,则会引发 timeout 异常。

如果进程不存在,则会引发 noproc 异常。

此函数的实现基于 terminate 系统消息,并且要求进程正确处理系统消息。有关系统消息的信息,请参见 sys 以及 OTP 设计原则中的 sys 和 proc_lib 部分。

链接到此函数

translate_initial_call(Process)

查看源代码
-spec translate_initial_call(Process) -> {Module, Function, Arity}
                                when
                                    Process :: dict_or_pid(),
                                    Module :: module(),
                                    Function :: atom(),
                                    Arity :: byte().

函数 c:i/0c:regs/0 使用此函数来呈现进程信息。

此函数提取使用此模块中的某个生成或启动函数启动的进程的初始调用,并将其转换为更有用的信息。Process 可以是 pid、整数元组(可以从中创建 pid)或通过 erlang:process_info(Pid) 函数调用提取的进程 Pid 的进程信息。

如果初始调用是对诸如 gen_servergen_event 之类的系统定义的行为之一进行的,则会将其转换为更有用的信息。如果生成了 gen_server,则返回的 Module 是回调模块的名称,Functioninit(启动新服务器的函数)。

一个 supervisor 和一个 supervisor_bridge 也都是 gen_server 进程。为了返回此进程是 supervisor 以及回调模块名称的信息,Modulesupervisor,而 Function 是 supervisor 回调模块的名称。Arity1,因为 init/1 函数最初在回调模块中被调用。

默认情况下,如果没有找到关于初始调用的信息,则返回 {proc_lib,init_p,5}。假设调用者知道该进程已使用 proc_lib 模块生成。