檢視原始碼 proc_lib (stdlib v6.2)
用於非同步和同步啟動遵循 OTP 設計原則的程序的函式。
此模組用於啟動遵循 OTP 設計原則的程序。 具體而言,此模組中的函式由 OTP 標準行為(例如,gen_server
和 gen_statem
)在啟動新程序時使用。 這些函式還可以用於啟動特殊程序,即符合 OTP 設計原則的用戶定義程序。 例如,請參閱 OTP 設計原則中的 sys 和 proc_lib 章節。
當程序啟動時,會初始化一些有用的資訊。 父程序的註冊名稱或程序識別符,以及父系的祖先,會與程序中最初呼叫的函式的相關資訊一起儲存。
雖然在「普通 Erlang」中,只有在退出原因為 normal
時,程序才算正常終止,但使用 proc_lib
啟動的程序,如果退出原因為 shutdown
或 {shutdown,Term}
,也算正常終止。shutdown
是應用程式(監督樹)停止時使用的原因。
當使用 proc_lib
啟動的程序異常終止時(即,退出原因不是 normal
、shutdown
或 {shutdown,Term}
時),會產生崩潰報告,並由 Kernel 設定的預設記錄器處理程式寫入終端。 有關在 Erlang/OTP 21.0 之前如何記錄崩潰報告的更多資訊,請參閱 SASL 使用者指南中的 SASL 錯誤記錄。
與「普通 Erlang」不同,proc_lib
程序不會產生錯誤報告,這些報告由模擬器寫入終端。所有例外都會轉換為預設 logger
處理程式忽略的退出。
崩潰報告包含先前儲存的資訊,例如祖先和初始函式、終止原因,以及有關因該程序終止而終止的其他程序的資訊。
另請參閱
摘要
類型
傳遞給 init_fail/3
的例外。 有關 Class
、Reason
和 Stacktrace
的描述,請參閱 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 相同(並且會呼叫它),但確保當程序喚醒時,例外處理和記錄會繼續按預期工作。
等同於 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
引發例外。 然後,start 函式會傳回 Ret
。
擷取使用此模組中的 spawn 或 start 函式之一啟動的程序的初始呼叫。Process
可以是 pid、整數元組(可以從中建立 pid),或透過 erlang:process_info(Pid)
函式呼叫擷取的程序 Pid
的程序資訊。
為目前程序設定標籤。 主要目的是協助偵錯未註冊的程序。 程序標籤可以用於工具和崩潰報告中以識別程序,但不一定要是唯一的或原子,如同註冊名稱一樣。 程序標籤可以是任何 term,例如 {worker_process, 1..N}
。
產生一個新程序,並依照本手冊頁開頭的說明進行初始化。 該程序會使用 spawn
BIF 產生。
產生一個新程序,並依照本手冊頁開頭的說明進行初始化。 該程序會使用 spawn_link
BIF 產生。
產生一個新程序,並依照本手冊頁開頭的說明進行初始化。 該程序會使用 erlang:spawn_opt
BIF 產生。
同步啟動一個新程序。 產生程序並等待它啟動。
同步啟動一個新程序。 產生程序並等待它啟動。 連結會以原子方式設定在新產生的程序上。
同步啟動一個新程序。 產生程序並等待它啟動。 監控會以原子方式設定在新產生的程序上。
命令程序以指定的 Reason
退出,並等待其終止。
類型
-type exception() :: {Class :: error | exit | throw, Reason :: term()} | {Class :: error | exit | throw, Reason :: term(), Stacktrace :: erlang:raise_stacktrace()}.
傳遞給 init_fail/3
的例外。 有關 Class
、Reason
和 Stacktrace
的描述,請參閱 erlang:raise/3
。
-type spawn_option() :: erlang:spawn_opt_option().
-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, 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。
-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])
。
傳回 undefined
或使用 proc_lib:set_label/1
設定的程序 Pid 的標籤。
-spec hibernate(Module, Function, Args) -> no_return() when Module :: module(), Function :: atom(), Args :: [term()].
此函式的功能與 hibernate/3
BIF 相同(並且會呼叫它),但確保當程序喚醒時,例外處理和記錄會繼續按預期工作。
對於使用 proc_lib
函式啟動的程序,請務必使用此函式,而不是 BIF。
-spec init_ack(Ret) -> ok when Ret :: term().
等同於 init_ack(Parent, Ret)
,其中 Parent
是呼叫 start/5
的程序。
此函式只能由已由 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(Parent, Return, Exception)
,其中 Parent
是呼叫 start/5
的程序。
此函式只能由已由 start[_link|_monitor]/3,4,5
函式啟動的程序使用。 它會告知 Parent
該程序初始化失敗,並立即根據 Exception
引發例外。 然後,start 函式會傳回 Ret
。
如需 Class
、Reason
和 Stacktrace
的說明,請參閱 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 的本機函式以及 arity,例如{some_module,-work/3-fun-0-,0}
(表示 fun 是在函式some_module:work/3
中建立的)。原因是保留 fun 會阻止模組的程式碼升級,並可能浪費大量記憶體。
-spec set_label(Label) -> ok when Label :: term().
為目前程序設定標籤。 主要目的是協助偵錯未註冊的程序。 程序標籤可以用於工具和崩潰報告中以識別程序,但不一定要是唯一的或原子,如同註冊名稱一樣。 程序標籤可以是任何 term,例如 {worker_process, 1..N}
。
請使用 proc_lib:get_label/1
來查詢程序描述。
-spec spawn(Node, Module, Function, Args) -> pid() when Node :: node(), Module :: module(), Function :: atom(), Args :: [term()].
產生一個新程序,並依照本手冊頁開頭的說明進行初始化。 該程序會使用 spawn
BIF 產生。
-spec spawn_link(Node, Module, Function, Args) -> pid() when Node :: node(), Module :: module(), Function :: atom(), Args :: [term()].
產生一個新程序,並依照本手冊頁開頭的說明進行初始化。 該程序會使用 spawn_link
BIF 產生。
-spec spawn_opt(Fun, SpawnOpts) -> pid() | {pid(), reference()} when Fun :: function(), SpawnOpts :: [erlang:spawn_opt_option()].
-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 產生。
-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,2
或 init_fail/2,3
之前失敗,則此函式會傳回 {error, Reason}
,其中 Reason
有點取決於例外狀況,就像程序連結的 {'EXIT',Pid,Reason}
訊息一樣。
如果 Time
指定為整數,則此函式會等待 Time
毫秒,讓新程序呼叫 init_ack/1,2
或 init_fail/2,3
,否則該程序會被終止,並傳回 Ret = {error, timeout}
。
如果指定,引數 SpawnOpts
會作為最後一個引數傳遞給 spawn_opt/4
BIF。
注意
不允許使用產生選項
monitor
。它會導致函式因badarg
的原因而失敗。使用產生選項
link
會設定與已產生程序的連結,就像 start_link/3,4,5 一樣。
-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
的原因而失敗。
-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,2
或 init_fail/2,3
中的 Ret
引數,而 Mon
是已設定的監視器的監視器參考。
如果此函式由於產生的程序退出而傳回,也就是傳回任何錯誤值,則會將 'DOWN'
訊息傳遞至呼叫程序,即使此函式逾時並終止產生的程序也是如此。
注意
不允許使用產生選項
monitor
。它會導致函式因badarg
的原因而失敗。使用產生選項
link
會設定與已產生程序的連結,就像 start_link/3,4,5 一樣。
-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 章節。
-spec translate_initial_call(Process) -> {Module, Function, Arity} when Process :: dict_or_pid(), Module :: module(), Function :: atom(), Arity :: byte().
函式 c:i/0
和 c:regs/0
使用此函式來呈現程序資訊。
此函式會擷取使用此模組中其中一個產生或啟動函式啟動的程序的初始呼叫,並將其轉譯為更有用的資訊。Process
可以是 PID、整數元組(可從中建立 PID)或透過 erlang:process_info(Pid)
函式呼叫擷取的程序 Pid
的程序資訊。
如果初始呼叫是呼叫其中一個系統定義的行為(例如 gen_server
或 gen_event
),則會將其轉譯為更有用的資訊。如果產生 gen_server
,則傳回的 Module
是回呼模組的名稱,而 Function
是 init
(啟動新伺服器的函式)。
supervisor
和 supervisor_bridge
也是 gen_server
程序。若要傳回此程序是 supervisor 以及回呼模組名稱的資訊,Module
是 supervisor
,而 Function
是 supervisor 回呼模組的名稱。Arity
是 1
,因為回呼模組中會先呼叫 init/1
函式。
依預設,如果找不到關於初始呼叫的任何資訊,則會傳回 {proc_lib,init_p,5}
。假設呼叫者知道該程序已使用 proc_lib
模組產生。