.TH proc_lib 3erl "stdlib 5.2.2" "Ericsson AB" "Erlang Module Definition" .SH NAME proc_lib \- Functions for asynchronous and synchronous start of processes adhering to the OTP design principles. .SH DESCRIPTION .LP This module is used to start processes adhering to the OTP Design Principles\&. Specifically, the functions in this module are used by the OTP standard behaviors (for example, \fIgen_server\fR\& and \fIgen_statem\fR\&) when starting new processes\&. The functions can also be used to start \fIspecial processes\fR\&, user-defined processes that comply to the OTP design principles\&. For an example, see section sys and proc_lib in OTP Design Principles\&. .LP Some useful information is initialized when a process starts\&. The registered names, or the process identifiers, of the parent process, and the parent ancestors, are stored together with information about the function initially called in the process\&. .LP While in "plain Erlang", a process is said to terminate normally only for exit reason \fInormal\fR\&, a process started using \fIproc_lib\fR\& is also said to terminate normally if it exits with reason \fIshutdown\fR\& or \fI{shutdown,Term}\fR\&\&. \fIshutdown\fR\& is the reason used when an application (supervision tree) is stopped\&. .LP When a process that is started using \fIproc_lib\fR\& terminates abnormally (that is, with another exit reason than \fInormal\fR\&, \fIshutdown\fR\&, or \fI{shutdown,Term}\fR\&), a \fIcrash report\fR\& is generated, which is written to terminal by the default logger handler setup by Kernel\&. For more information about how crash reports were logged prior to Erlang/OTP 21\&.0, see SASL Error Logging in the SASL User\&'s Guide\&. .LP Unlike in "plain Erlang", \fIproc_lib\fR\& processes will not generate \fIerror reports\fR\&, which are written to the terminal by the emulator\&. All exceptions are converted to \fIexits\fR\& which are ignored by the default \fIlogger\fR\& handler\&. .LP The crash report contains the previously stored information, such as ancestors and initial function, the termination reason, and information about other processes that terminate as a result of this process terminating\&. .SH DATA TYPES .nf \fBspawn_option()\fR\& = erlang:spawn_opt_option() .br .fi .RS .LP See \fIerlang:spawn_opt/2,3,4,5\fR\&\&. .RE .nf \fBstart_spawn_option()\fR\& = .br link | .br {priority, erlang:priority_level()} | .br {fullsweep_after, integer() >= 0} | .br {min_heap_size, integer() >= 0} | .br {min_bin_vheap_size, integer() >= 0} | .br {max_heap_size, erlang:max_heap_size()} | .br {message_queue_data, erlang:message_queue_data()} .br .fi .RS .LP A restricted set of spawn options\&. Most notably \fImonitor\fR\& is \fInot\fR\& part of these options\&. .RE .nf \fBdict_or_pid()\fR\& = .br pid() | .br (ProcInfo :: [term()]) | .br {X :: integer(), Y :: integer(), Z :: integer()} .br .fi .SH EXPORTS .LP .nf .B format(CrashReport) -> string() .br .fi .br .RS .LP Types: .RS 3 CrashReport = [term()] .br .RE .RE .RS .LP Equivalent to \fIformat(CrashReport, latin1)\fR\&\&. .RE .LP .nf .B format(CrashReport, Encoding) -> string() .br .fi .br .RS .LP Types: .RS 3 CrashReport = [term()] .br Encoding = latin1 | unicode | utf8 .br .RE .RE .RS .LP .RS -4 .B Note: .RE This function is deprecated in the sense that the \fIerror_logger\fR\& is no longer the preferred interface for logging in Erlang/OTP\&. A new logging API was added in Erlang/OTP 21\&.0, but legacy \fIerror_logger\fR\& handlers can still be used\&. New Logger handlers do not need to use this function, since the formatting callback (\fIreport_cb\fR\&) is included as metadata in the log event\&. .LP This function can be used by a user-defined legacy \fIerror_logger\fR\& event handler to format a crash report\&. The crash report is sent using \fIlogger(3erl)\fR\&, and the event to be handled is of the format \fI{error_report, GL, {Pid, crash_report, CrashReport}}\fR\&, where \fIGL\fR\& is the group leader pid of process \fIPid\fR\& that sent the crash report\&. .RE .LP .nf .B format(CrashReport, Encoding, Depth) -> string() .br .fi .br .RS .LP Types: .RS 3 CrashReport = [term()] .br Encoding = latin1 | unicode | utf8 .br Depth = unlimited | integer() >= 1 .br .RE .RE .RS .LP .RS -4 .B Note: .RE This function is deprecated in the sense that the \fIerror_logger\fR\& is no longer the preferred interface for logging in Erlang/OTP\&. A new logging API was added in Erlang/OTP 21\&.0, but legacy \fIerror_logger\fR\& handlers can still be used\&. New Logger handlers do not need to used this function, since the formatting callback (\fIreport_cb\fR\&) is included as metadata in the log event\&. .LP This function can be used by a user-defined legacy \fIerror_logger\fR\& event handler to format a crash report\&. When Depth is specified as a positive integer, it is used in the format string to limit the output as follows: \fIio_lib:format("~P", [Term,Depth])\fR\&\&. .RE .LP .nf .B hibernate(Module, Function, Args) -> no_return() .br .fi .br .RS .LP Types: .RS 3 Module = module() .br Function = atom() .br Args = [term()] .br .RE .RE .RS .LP This function does the same as (and does call) the \fIhibernate/3\fR\& BIF, but ensures that exception handling and logging continues to work as expected when the process wakes up\&. .LP Always use this function instead of the BIF for processes started using \fIproc_lib\fR\& functions\&. .RE .LP .nf .B init_ack(Ret) -> ok .br .fi .br .nf .B init_ack(Parent, Ret) -> ok .br .fi .br .RS .LP Types: .RS 3 Parent = pid() .br Ret = term() .br .RE .RE .RS .LP This function must only be used by a process that has been started by a \fIstart[_link|_monitor]/3,4,5\fR\& function\&. It tells \fIParent\fR\& that the process has initialized itself and started\&. .LP Function \fIinit_ack/1\fR\& uses the parent value previously stored by the start function used\&. .LP If neither this function nor \fIinit_fail/2,3\fR\& is called by the started process, the start function returns an error tuple when the started process exits, or when the start function time-out (if used) has passed, see \fIstart/3,4,5\fR\&\&. .LP .RS -4 .B Warning: .RE Do not use this function to return an error indicating that the process start failed\&. When doing so the start function can return before the failing process has exited, which may block VM resources required for a new start attempt to succeed\&. Use \fIinit_fail/2,3\fR\& for that purpose\&. .LP The following example illustrates how this function and \fIproc_lib:start_link/3\fR\& are used: .LP .nf -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(). \&... .fi .RE .LP .B init_fail(Ret, Exception) -> no_return() .br .B init_fail(Parent, Ret, Exception) -> no_return() .br .RS .LP Types: .RS 3 Parent = pid() .br Ret = term() .br Exception = {Class, Reason} | {Class, Reason, Stacktrace} .br .RE .RE .RS .LP This function must only be used by a process that has been started by a \fIstart[_link|_monitor]/3,4,5\fR\& function\&. It tells \fIParent\fR\& that the process has failed to initialize, and immediately raises an exception according to \fIException\fR\&\&. The start function then returns \fIRet\fR\&\&. .LP See \fIerlang:raise/3\fR\& for a description of \fIClass\fR\&, \fIReason\fR\& and \fIStacktrace\fR\&\&. .LP Function \fIinit_fail/2\fR\& uses the parent value previously stored by the start function used\&. .LP .RS -4 .B Warning: .RE Do not consider catching the exception from this function\&. That would defeat its purpose\&. A process started by a \fIstart[_link|_monitor]/3,4,5\fR\& function should end in a value (that will be ignored) or an exception that will be handled by this module\&. See Description\&. .LP If neither this function nor \fIinit_ack/1,2\fR\& is called by the started process, the start function returns an error tuple when the started process exits, or when the start function time-out (if used) has passed, see \fIstart/3,4,5\fR\&\&. .LP The following example illustrates how this function and \fIproc_lib:start_link/3\fR\& can be used: .LP .nf -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(). \&... .fi .RE .LP .nf .B initial_call(Process) -> {Module, Function, Args} | false .br .fi .br .RS .LP Types: .RS 3 Process = dict_or_pid() .br Module = module() .br Function = atom() .br Args = [atom()] .br .RE .RE .RS .LP Extracts the initial call of a process that was started using one of the spawn or start functions in this module\&. \fIProcess\fR\& can either be a pid, an integer tuple (from which a pid can be created), or the process information of a process \fIPid\fR\& fetched through an \fIerlang:process_info(Pid)\fR\& function call\&. .LP .RS -4 .B Note: .RE The list \fIArgs\fR\& no longer contains the arguments, but the same number of atoms as the number of arguments; the first atom is \fI\&'Argument__1\&'\fR\&, the second \fI\&'Argument__2\&'\fR\&, and so on\&. The reason is that the argument list could waste a significant amount of memory, and if the argument list contained funs, it could be impossible to upgrade the code for the module\&. .LP If the process was spawned using a fun, \fIinitial_call/1\fR\& no longer returns the fun, but the module, function for the local function implementing the fun, and the arity, for example, \fI{some_module,-work/3-fun-0-,0}\fR\& (meaning that the fun was created in function \fIsome_module:work/3\fR\&)\&. The reason is that keeping the fun would prevent code upgrade for the module, and that a significant amount of memory could be wasted\&. .RE .LP .nf .B spawn(Fun) -> pid() .br .fi .br .nf .B spawn(Node, Fun) -> pid() .br .fi .br .nf .B spawn(Module, Function, Args) -> pid() .br .fi .br .nf .B spawn(Node, Module, Function, Args) -> pid() .br .fi .br .RS .LP Types: .RS 3 Node = node() .br Fun = function() .br Module = module() .br Function = atom() .br Args = [term()] .br .RE .RE .RS .LP Spawns a new process and initializes it as described in the beginning of this manual page\&. The process is spawned using the \fIspawn\fR\& BIFs\&. .RE .LP .nf .B spawn_link(Fun) -> pid() .br .fi .br .nf .B spawn_link(Node, Fun) -> pid() .br .fi .br .nf .B spawn_link(Module, Function, Args) -> pid() .br .fi .br .nf .B spawn_link(Node, Module, Function, Args) -> pid() .br .fi .br .RS .LP Types: .RS 3 Node = node() .br Fun = function() .br Module = module() .br Function = atom() .br Args = [term()] .br .RE .RE .RS .LP Spawns a new process and initializes it as described in the beginning of this manual page\&. The process is spawned using the \fIspawn_link\fR\& BIFs\&. .RE .LP .nf .B spawn_opt(Fun, SpawnOpts) -> pid() | {pid(), reference()} .br .fi .br .nf .B spawn_opt(Node, Function, SpawnOpts) -> .B pid() | {pid(), reference()} .br .fi .br .nf .B spawn_opt(Module, Function, Args, SpawnOpts) -> .B pid() | {pid(), reference()} .br .fi .br .nf .B spawn_opt(Node, Module, Function, Args, SpawnOpts) -> .B pid() | {pid(), reference()} .br .fi .br .RS .LP Types: .RS 3 Node = node() .br Fun = function() .br Module = module() .br Function = atom() .br Args = [term()] .br SpawnOpts = [spawn_option()] .br .RE .RE .RS .LP Spawns a new process and initializes it as described in the beginning of this manual page\&. The process is spawned using the \fIerlang:spawn_opt\fR\& BIFs\&. .RE .LP .nf .B start(Module, Function, Args) -> Ret .br .fi .br .nf .B start(Module, Function, Args, Time) -> Ret .br .fi .br .nf .B start(Module, Function, Args, Time, SpawnOpts) -> Ret .br .fi .br .RS .LP Types: .RS 3 Module = module() .br Function = atom() .br Args = [term()] .br Time = timeout() .br SpawnOpts = [start_spawn_option()] .br Ret = term() | {error, Reason :: term()} .br .RE .RE .RS .LP Starts a new process synchronously\&. Spawns the process and waits for it to start\&. .LP To indicate a succesful start, the started process \fImust\fR\& call \fIinit_ack(Parent, Ret)\fR\& where \fIParent\fR\& is the process that evaluates this function, or \fIinit_ack(Ret)\fR\&\&. \fIRet\fR\& is then returned by this function\&. .LP If the process fails to start, it \fImust\fR\& fail; preferably by calling \fIinit_fail(Parent, Ret, Exception)\fR\& where \fIParent\fR\& is the process that evaluates this function, or \fIinit_fail(Ret, Exception)\fR\&\&. \fIRet\fR\& is then returned by this function, and the started process fails with \fIException\fR\&\&. .LP If the process instead fails before calling \fIinit_ack/1,2\fR\& or \fIinit_fail/2,3\fR\&, this function returns \fI{error, Reason}\fR\& where \fIReason\fR\& depends a bit on the exception just like for a process link \fI{\&'EXIT\&',Pid,Reason}\fR\& message\&. .LP If \fITime\fR\& is specified as an integer, this function waits for \fITime\fR\& milliseconds for the new process to call \fIinit_ack/1,2\fR\& or \fIinit_fail/2,3\fR\&, otherwise the process gets killed and \fIRet = {error, timeout}\fR\& is returned\&. .LP Argument \fISpawnOpts\fR\&, if specified, is passed as the last argument to the \fIspawn_opt/2,3,4,5\fR\& BIF\&. .LP .RS -4 .B Note: .RE Using spawn option \fImonitor\fR\& is not allowed\&. It causes the function to fail with reason \fIbadarg\fR\&\&. .LP Using spawn option \fIlink\fR\& will set a link to the spawned process, just like start_link/3,4,5\&. .RE .LP .nf .B start_link(Module, Function, Args) -> Ret .br .fi .br .nf .B start_link(Module, Function, Args, Time) -> Ret .br .fi .br .nf .B start_link(Module, Function, Args, Time, SpawnOpts) -> Ret .br .fi .br .RS .LP Types: .RS 3 Module = module() .br Function = atom() .br Args = [term()] .br Time = timeout() .br SpawnOpts = [start_spawn_option()] .br Ret = term() | {error, Reason :: term()} .br .RE .RE .RS .LP Starts a new process synchronously\&. Spawns the process and waits for it to start\&. A link is atomically set on the newly spawned process\&. .LP .RS -4 .B Note: .RE If the started process gets killed or crashes with a reason that is not `normal`, the process link will kill the calling process so this function does not return, unless the calling process traps exits\&. For example, if this function times out it will kill the spawned process, and then the link might kill the calling process\&. .LP Besides setting a link on the spawned process this function behaves like start/3,4,5\&. .LP When the calling process traps exits; if this function returns due to the spawned process exiting (any error return), this function receives (consumes) the \fI\&'EXIT\&'\fR\& message, also when this function times out and kills the spawned process\&. .LP .RS -4 .B Note: .RE Using spawn option \fImonitor\fR\& is not allowed\&. It causes the function to fail with reason \fIbadarg\fR\&\&. .RE .LP .nf .B start_monitor(Module, Function, Args) -> {Ret, Mon} .br .fi .br .nf .B start_monitor(Module, Function, Args, Time) -> {Ret, Mon} .br .fi .br .nf .B start_monitor(Module, Function, Args, Time, SpawnOpts) -> .B {Ret, Mon} .br .fi .br .RS .LP Types: .RS 3 Module = module() .br Function = atom() .br Args = [term()] .br Time = timeout() .br SpawnOpts = [start_spawn_option()] .br Mon = reference() .br Ret = term() | {error, Reason :: term()} .br .RE .RE .RS .LP Starts a new process synchronously\&. Spawns the process and waits for it to start\&. A monitor is atomically set on the newly spawned process\&. .LP Besides setting a monitor on the spawned process this function behaves like start/3,4,5\&. .LP The return value is \fI{Ret, Mon}\fR\& where \fIRet\fR\& corresponds to the \fIRet\fR\& argument in the call to \fIinit_ack/1,2\fR\& or \fIinit_fail/2,3\fR\&, and \fIMon\fR\& is the monitor reference of the monitor that has been set up\&. .LP If this function returns due to the spawned process exiting, that is returns any error value, a \fI\&'DOWN\&'\fR\& message will be delivered to the calling process, also when this function times out and kills the spawned process\&. .LP .RS -4 .B Note: .RE Using spawn option \fImonitor\fR\& is not allowed\&. It causes the function to fail with reason \fIbadarg\fR\&\&. .LP Using spawn option \fIlink\fR\& will set a link to the spawned process, just like start_link/3,4,5\&. .RE .LP .nf .B stop(Process) -> ok .br .fi .br .RS .LP Types: .RS 3 Process = pid() | RegName | {RegName, node()} .br .RE .RE .RS .LP Equivalent to \fIstop(Process, normal, infinity)\fR\&\&. .RE .LP .nf .B stop(Process, Reason, Timeout) -> ok .br .fi .br .RS .LP Types: .RS 3 Process = pid() | RegName | {RegName, node()} .br Reason = term() .br Timeout = timeout() .br .RE .RE .RS .LP Orders the process to exit with the specified \fIReason\fR\& and waits for it to terminate\&. .LP Returns \fIok\fR\& if the process exits with the specified \fIReason\fR\& within \fITimeout\fR\& milliseconds\&. .LP If the call times out, a \fItimeout\fR\& exception is raised\&. .LP If the process does not exist, a \fInoproc\fR\& exception is raised\&. .LP The implementation of this function is based on the \fIterminate\fR\& system message, and requires that the process handles system messages correctly\&. For information about system messages, see \fIsys(3erl)\fR\& and section sys and proc_lib in OTP Design Principles\&. .RE .LP .nf .B translate_initial_call(Process) -> {Module, Function, Arity} .br .fi .br .RS .LP Types: .RS 3 Process = dict_or_pid() .br Module = module() .br Function = atom() .br Arity = byte() .br .RE .RE .RS .LP This function is used by functions \fIc:i/0\fR\& and \fIc:regs/0\fR\& to present process information\&. .LP This function extracts the initial call of a process that was started using one of the spawn or start functions in this module, and translates it to more useful information\&. \fIProcess\fR\& can either be a pid, an integer tuple (from which a pid can be created), or the process information of a process \fIPid\fR\& fetched through an \fIerlang:process_info(Pid)\fR\& function call\&. .LP If the initial call is to one of the system-defined behaviors such as \fIgen_server\fR\& or \fIgen_event\fR\&, it is translated to more useful information\&. If a \fIgen_server\fR\& is spawned, the returned \fIModule\fR\& is the name of the callback module and \fIFunction\fR\& is \fIinit\fR\& (the function that initiates the new server)\&. .LP A \fIsupervisor\fR\& and a \fIsupervisor_bridge\fR\& are also \fIgen_server\fR\& processes\&. To return information that this process is a supervisor and the name of the callback module, \fIModule\fR\& is \fIsupervisor\fR\& and \fIFunction\fR\& is the name of the supervisor callback module\&. \fIArity\fR\& is \fI1\fR\&, as the \fIinit/1\fR\& function is called initially in the callback module\&. .LP By default, \fI{proc_lib,init_p,5}\fR\& is returned if no information about the initial call can be found\&. It is assumed that the caller knows that the process has been spawned with the \fIproc_lib\fR\& module\&. .RE .SH "SEE ALSO" .LP \fIerror_logger(3erl)\fR\& .LP \fIlogger(3erl)\fR\&