A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from http://www.erlang.org/doc/system/ref_man_processes below:

Processes — Erlang System Documentation v28.0.1

Processes

Erlang is designed for massive concurrency. Erlang processes are lightweight (grow and shrink dynamically) with small memory footprint, fast to create and terminate, and the scheduling overhead is low.

Process Creation

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 starts executing in Module:Name(Arg1,...,ArgN) where the arguments are the elements of the (possible empty) Args argument list.

There exist a number of different spawn BIFs:

Registered Processes

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:

Table: Name Registration BIFs

Process Aliases

When sending a message to a process, the receiving process can be identified by a Pid, a registered name, or a process alias which is a term of the type reference. The typical use case that process aliases were designed for is a request/reply scenario. Using a process alias when sending the reply makes it possible for the receiver of the reply to prevent the reply from reaching its message queue if the operation times out or if the connection between the processes is lost.

A process alias can be used as identifier of the receiver when sending a message using the send operator (!) or send BIFs such as erlang:send/2. As long as the process alias is active, messages will be delivered the same way as if the process identifier of the process that created the alias had been used. When the alias has been deactivated, messages sent using the alias will be dropped before entering the message queue of the receiver. Note that messages that at deactivation time already have entered the message queue will not be removed.

A process alias is created either by calling one of the alias/0,1 BIFs or by creating an alias and a monitor simultaneously. If the alias is created together with a monitor, the same reference will be used both as monitor reference and alias. Creating a monitor and an alias at the same time is done by passing the {alias, _} option to the monitor/3 BIF. The {alias, _} option can also be passed when creating a monitor via spawn_opt(), or spawn_request().

A process alias can be deactivated by the process that created it by calling the unalias/1 BIF. It is also possible to automatically deactivate an alias on certain events. See the documentation of the alias/1 BIF, and the {alias, _} option of the monitor/3 BIF for more information about automatic deactivation of aliases.

It is not possible to:

These are all intentional design decisions relating to performance, scalability, and distribution transparency.

Process Termination

When a process terminates, it always terminates with an exit reason. The reason can 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 an exit reason {Reason,Stack} when a run-time error occurs. See Exit Reasons.

A process can terminate itself by calling one of the following BIFs:

The process then terminates with reason Reason for exit/1 or {Reason,Stack} for the others.

A process can also be terminated if it receives an exit signal with another exit reason than normal, see Error Handling.

Signals

All communication between Erlang processes and Erlang ports is done by sending and receiving asynchronous signals. The most common signals are Erlang message signals. A message signal can be sent using the send operator !. A received message can be fetched from the message queue by the receiving process using the receive expression.

Synchronous communication can be broken down into multiple asynchronous signals. An example of such a synchronous communication is a call to the erlang:process_info/2 BIF when the first argument does not equal the process identifier of the calling process. The caller sends an asynchronous signal requesting information, and then blocks waiting for the reply signal containing the requested information. When the request signal reaches its destination, the destination process replies with the requested information.

Sending Signals

There are many signals that processes and ports use to communicate. The list below contains the most important signals. In all the cases of request/reply signal pairs, the request signal is sent by the process calling the specific BIF, and the reply signal is sent back to it when the requested operation has been performed.

The clock service, the name service, the timer service, and the spawn service mentioned previously are services provided by the runtime system. Each of these services consists of multiple independently executing entities. Such a service can be viewed as a group of processes, and could actually be implemented like that. Since each service consists of multiple independently executing entities, the order between multiple signals sent from one service to one process is not preserved. Note that this does not violate the signal ordering guarantee of the language.

The realization of the signals described earlier may change both at runtime and due to changes in implementation. You may be able to detect such changes using receive tracing or by inspecting message queues. However, these are internal implementation details of the runtime system that you should not rely on. As an example, many of the reply signals are ordinary message signals. When the operation is synchronous, the reply signals do not have to be message signals. The current implementation takes advantage of this and, depending on the state of the system, use alternative ways of delivering the reply signals. The implementation of these reply signals may also, at any time, be changed to not use message signals where it previously did.

Receiving Signals

Signals are received asynchronously and automatically. There is nothing a process must do to handle the reception of signals, or can do to prevent it. In particular, signal reception is not tied to the execution of a receive expression, but can happen anywhere in the execution flow of a process.

When a signal is received by a process, some kind of action is taken. The specific action taken depends on the signal type, contents of the signal, and the state of the receiving process. Actions taken for the most common signals:

Note that some actions taken when a signal is received involves scheduling further actions which will result in a reply signal when these scheduled actions have completed. This implies that the reply signals may be sent in a different order than the order of the incoming signals that triggered these operations. This does, however, not violate the signal ordering guarantee of the language.

Adding Messages to the Message Queue

When a message signal is received, the action taken is to add the message to the message queue. The actions of other signals at receptions may also add messages to the message queue (see above). Unless the receiving process has enabled priority messages, all messages are added to the end of the message queue. In the case that the receiver has not enabled priority messages, the order of the messages in the message queue will reflect the order in which the signals corresponding to the messages in the queue were received. Messages corresponding to signals from the same sender will then also be ordered in the same order as the signals were sent due to the signal ordering guarantee of the language.

As of OTP 28.0 a process may enable reception of priority messages. If the receiving process has enabled priority messages, the receiver will at reception of a message signal, or another signal that is converted into a message, check if it should be accepted as a priority message or not. If accepted as a priority message, it will be added after the last accepted priority message in the queue; otherwise, it will be treated as an ordinary message and will be added at the end of the message queue.

Figure 1.

When messages that have been accepted as priority messages exist in the message queue, the order of the messages in the message queue will not reflect the order in which the signals corresponding to the messages in the queue were received. However, the order of priority messages corresponds to the order in which those corresponding signals were received, and the order of ordinary messages corresponds to the order in which those corresponding signals were received. Thus, two messages sent from the same sender may be in another order than the order they were sent.

Note that priority messages do not violate the signal ordering guarantee of the language. The signals are still delivered in the same order to the receiving process. The only difference is how messages are added to the message queue after the signals have been received by the receiving process.

A receive expression will select the first message, from the start, in the message queue that matches, just as if only ordinary messages exist in the message queue. The total message queue length in figure 1 equals P+M. The lengths P and M are not be visible, only the total message queue length can be determined. There is no way for the Erlang code to distinguish a priority message from an ordinary message when fetching a message from the message queue. Such knowledge needs to be part of the message protocol that the process should adhere to.

Enabling Priority Message Reception Warning

Priority messages are intended to solve very specific problems where it previously was very hard to solve such problems efficiently using ordinary signaling. You very seldom need to resort to usage of priority messages. Receiving processes have not been optimized for handling large amounts of priority messages. If a process accumulate a large amount of priority messages, the design of that message protocol should be redesigned since this is not how priority messages are intended to be used.

A process can enable priority message reception by creating a priority process alias or shorter priority alias. Such an alias is created by calling the erlang:alias/1 BIF with the priority option. This priority alias then needs to be distributed to processes that are to be able to send priority messages to the process that created the alias. In order to send a priority message, the priority alias should be passed to the erlang:send/3 BIF at the same time as the option priority is passed in the option list. Note that both the priority alias as well as the priority option need to be passed in order for the message to be accepted as a priority message.

The priority alias can also be used for sending exit signals which will be handled as priority messages if the receiver is trapping exits. In this case the priority alias should be passed as first argument to the erlang:exit/3 BIF and the option priority should be passed in the option list. Also in this case both the priority alias as well as the priority option need to be passed in order for the message to be accepted as a priority message. Note that this only affects how a potential exit message is handled if the receiver is trapping exits. The exit signal as such will not get a higher priority.

If the creator of the priority alias deactivates the alias, the signals sent using the alias will be dropped the same way as for any process alias.

Priority message reception can also be enabled for exit signals due to broken links and messages triggered due to monitors. Since these signals are not sent when a process calls a specific function for sending a signal, but instead are sent when specific events occur in the system, a priority alias cannot be used for this.

In order to enable priority message reception of messages triggered by a monitor, the process that creates the monitor needs to create it using the erlang:monitor/3 BIF and pass the option priority. A message received due to the the monitor being triggered will then be handled as a priority message.

In order to enable priority message reception for an exit signals due to broken links, the process that wants the exit signal as a priority message, needs to call the erlang:link/2 BIF with the priority option. The priority option will only enable priority message handling of exit signals for the process that called the erlang:link/2 BIF with the priority option. Also in this case, this only affects how a potential exit message is handled if the receiver is trapping exits.

Directly Visible Erlang Resources

As described earlier, exit signals due to links, down signals, and reply signals from an exiting process due to alive_requests are not sent until all directly visible Erlang resources held by the terminating process have been released. With directly visible Erlang resources we here mean all resources made available by the language excluding resources held by heap data, dirty native code execution and the process identifier of the terminating process. Examples of directly visible Erlang resources are registered name and ETS tables.

The Excluded Resources

The process identifier of the process cannot be released for reuse until everything regarding the process has been released.

A process executing dirty native code in a NIF when it receives an exit signal will be set into an exiting state even if it is still executing dirty native code. Directly visible Erlang resources will be released, but the runtime system cannot force the native code to stop executing. The runtime system tries to prevent the execution of the dirty native code from affecting other processes by, for example, disabling functionality such as enif_send() when used from a terminated process, but if the NIF is not well behaved it can still affect other processes. A well behaved dirty NIF should test if the process it is executing in has exited, and if so stop executing.

In the general case, the heap of a process cannot be removed before all signals that it needs to send have been sent. Resources held by heap data are the memory blocks containing the heap, but also include things referred to from the heap such as off heap binaries, and resources held via NIF resource objects on the heap.

Delivery of Signals

The amount of time that passes between the time a signal is sent and the arrival of the signal at the destination is unspecified but positive. If the receiver has terminated, the signal does not arrive, but it can trigger another signal. For example, a link signal sent to a non-existing process triggers an exit signal, which is sent back to where the link signal originated from. When communicating over the distribution, signals can be lost if the distribution channel goes down.

The only signal ordering guarantee given is the following: if an entity sends multiple signals to the same destination entity, the order is preserved; that is, if A sends a signal S1 to B, and later sends signal S2 to B, S1 is guaranteed not to arrive after S2. Note that S1 may, or may not have been lost.

Irregularities

The irregularities mentioned earlier cannot be fixed as they have been part of Erlang too long and it would break a lot of existing code.

Links

Two processes can be linked to each other. Also a process and a port that reside on the same node can be linked to each other. A link between two processes can be created if one of them calls the link/1 BIF with the process identifier of the other process as argument. Links can also be created using one the following spawn BIFs spawn_link(), spawn_opt(), or spawn_request(). The spawn operation and the link operation will be performed atomically, in these cases.

If one of the participants of a link terminates, it will send an exit signal to the other participant. The exit signal will contain the exit reason of the terminated participant.

A link can be removed by calling the unlink/1 BIF.

Links are bidirectional and there can only be one link between two processes. Repeated calls to link() have no effect. Either one of the involved processes may create or remove a link.

Links are used to monitor the behavior of other processes, see Error Handling.

Error Handling

Erlang has a built-in feature for error handling between processes. Terminating processes emit exit signals to all linked processes, which can 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.

See OTP Design Principles for more information about OTP supervision trees, which use this feature.

Sending Exit Signals

When a process or port terminates it will send exit signals to all processes and ports that it is linked to. The exit signal will contain the following information:

Exit signals can also be sent explicitly by calling the exit(PidOrPort, Reason) BIF. The exit signal is sent to the process or port identified by the PidOrPort argument. The exit signal sent will contain the following information:

Receiving Exit Signals

What happens when a process receives an exit signal depends on:

Based on the above states, the following will happen when an exit signal is received by a process:

Monitors

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) creates several independent monitors, and each one sends a 'DOWN' message when Pid terminates.

A monitor can be removed by calling erlang:demonitor(Ref).

Monitors can be created for processes with registered names, also at other nodes.

Process Dictionary

Each process has its own process dictionary, accessed by calling the following BIFs:


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4