Erlang is designed for massive concurrency. Erlang processes are light-weight (grow and shrink dynamically) with small memory footprint, fast to create and terminate and the scheduling overhead is low.
A process is created by calling spawn
:
spawn(Module, Name, Args) -> pid() Module = Name = atom() Args = [Arg1,...,ArgN] ArgI = term()
spawn
creates a new process and returns the pid.
The new process will start executing in
Module:Name(Arg1,...,ArgN)
where the arguments is
the elements of the (possible empty) Args
argument list.
There exist a number of other spawn
BIFs, for example
spawn/4
for spawning a process at another node.
Besides addressing a process by using its pid, there are also BIFs for registering a process under a name. The name must be an atom and is automatically unregistered if the process terminates:
register(Name, Pid)
|
Associates the name Name , an atom, with
the process Pid .
|
registered()
|
Returns a list of names which have been registered using
register/2 .
|
whereis(Name)
|
Returns the pid registered under Name , or
undefined if the name is not registered.
|
When a process terminates, it always terminates with an exit reason. The reason may be any term.
A process is said to terminate normally, if the exit
reason is the atom normal
. A process with no more code to
execute terminates normally.
A process terminates with exit reason {Reason,Stack}
when a run-time error occurs. See
Error and Error
Handling.
A process can terminate itself by calling one of the BIFs
exit(Reason)
,
erlang:error(Reason)
, erlang:error(Reason, Args)
,
erlang:fault(Reason)
or erlang:fault(Reason, Args)
.
The process then terminates with reason Reason
for
exit/1
or {Reason,Stack} for the others
.
A process may also be terminated if it receives an exit signal
with another exit reason than normal
, see
Error Handling below.
Processes communicate by sending and receiving messages. Messages are sent by using the send operator ! and received by calling receive.
Message sending is asynchronous and safe, the message is guaranteed to eventually reach the recipient, provided that the recipient exists.
Two processes can be linked to each other. A link
between two processes Pid1
and Pid2
is created
by Pid1
calling the BIF link(Pid2)
(or vice versa).
There also exists a number a spawn_link
BIFs, which spawns
and links to a process in one operation.
Links are bidirectional and there can only be one link between
two processes. Repeated calls to link(Pid)
have no effect.
A link can be removed by calling the BIF unlink(Pid)
.
Links are used to monitor the behaviour of other processes, see Error Handling below.
Erlang has a built-in feature for error handling between processes. Terminating processes will emit exit signals to all linked processes, which may terminate as well or handle the exit in some way. This feature can be used to build hierarchical program structures where some processes are supervising other processes, for example restarting them if they terminate abnormally.
Refer to OTP Design Principles for more information about OTP supervision trees, which uses this feature.
When a process terminates, it will terminate with an exit reason as explained in Process Termination above. This exit reason is emitted in an exit signal to all linked processes.
A process can also call the function exit(Pid,Reason)
.
This will result in an exit signal with exit reason
Reason
being emitted to Pid
, but does not affect
the calling process.
The default behaviour when a process receives an exit signal
with an exit reason other than normal
, is to terminate
and in turn emit exit signals with the same exit reason to its
linked processes. An exit signal with reason normal
is
ignored.
A process can be set to trap exit signals by calling:
process_flag(trap_exit, true)
When a process is trapping exits, it will not terminate when
an exit signal is received. Instead, the signal is transformed
into a message {'EXIT',FromPid,Reason}
which is put into
the mailbox of the process just like a regular message.
An exception to the above is if the exit reason is kill
,
that is if exit(Pid,kill)
has been called. This will
unconditionally terminate the process, regardless of if it is
trapping exit signals or not.
An alternative to links are monitors. A process
Pid1
can create a monitor for Pid2
by calling
the BIF erlang:monitor(process, Pid2)
. The function returns
a reference Ref
.
If Pid2
terminates with exit reason Reason
, a
'DOWN' message is sent to Pid1
:
{'DOWN', Ref, process, Pid2, Reason}
If Pid2
does not exist, the 'DOWN' message is sent
immediately with Reason
set to noproc
.
Monitors are unidirectional. Repeated calls to
erlang:monitor(process, Pid)
will create several,
independent monitors and each one will send a 'DOWN' message when
Pid
terminates.
A monitor can be removed by calling
erlang:demonitor(Ref)
.
It is possible to create monitors for processes with registered names, also at other nodes.
Each process has its own process dictionary, accessed by calling the following BIFs:
put(Key, Value) get(Key) get() get_keys(Value) erase(Key) erase()