summaryrefslogtreecommitdiff
path: root/system/doc/reference_manual/processes.xml
blob: 53f13969e3e3550da74c1e42e432eb6fa9be83d7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE chapter SYSTEM "chapter.dtd">

<chapter>
  <header>
    <copyright>
      <year>2003</year><year>2015</year>
      <holder>Ericsson AB. All Rights Reserved.</holder>
    </copyright>
    <legalnotice>
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
 
          http://www.apache.org/licenses/LICENSE-2.0

      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      See the License for the specific language governing permissions and
      limitations under the License.
    
    </legalnotice>

    <title>Processes</title>
    <prepared></prepared>
    <docno></docno>
    <date></date>
    <rev></rev>
    <file>processes.xml</file>
  </header>

  <section>
    <title>Processes</title>
    <p>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.</p>
  </section>

  <section>
    <title>Process Creation</title>
    <p>A process is created by calling <c>spawn</c>:</p>
    <pre>
spawn(Module, Name, Args) -> pid()
  Module = Name = atom()
  Args = [Arg1,...,ArgN]
    ArgI = term()</pre>
    <p><c>spawn</c> creates a new process and returns the pid.</p>
    <p>The new process starts executing in
      <c>Module:Name(Arg1,...,ArgN)</c> where the arguments are
      the elements of the (possible empty) <c>Args</c> argument list.</p>
    <p>There exist a number of other <c>spawn</c> BIFs, for example,
      <c>spawn/4</c> for spawning a process at another node.</p>
  </section>

  <section>
    <title>Registered Processes</title>
    <p>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:</p>
    <table>
      <row>
        <cell align="left" valign="middle"><em>BIF</em></cell>
        <cell align="left" valign="middle"><em>Description</em></cell>
      </row>
      <row>
        <cell align="left" valign="middle"><c>register(Name, Pid)</c></cell>
        <cell align="left" valign="middle">Associates the name <c>Name</c>, an atom, with the process <c>Pid</c>.</cell>
      </row>
      <row>
        <cell align="left" valign="middle"><c>registered()</c></cell>
        <cell align="left" valign="middle">Returns a list of names that
        have been registered using <c>register/2</c>.</cell>
      </row>
      <row>
        <cell align="left" valign="middle"><c>whereis(Name)</c></cell>
        <cell align="left" valign="middle">Returns the pid registered
        under <c>Name</c>, or <c>undefined </c>if the name is not
        registered.</cell>
      </row>
      <tcaption>Name Registration BIFs</tcaption>
    </table>
  </section>

  <section>
    <marker id="term"></marker>
    <title>Process Termination</title>
    <p>When a process terminates, it always terminates with an
      <em>exit reason</em>. The reason can be any term.</p>
    <p>A process is said to terminate <em>normally</em>, if the exit
      reason is the atom <c>normal</c>. A process with no more code to
      execute terminates normally.</p>
    <p>A process terminates with an exit reason <c>{Reason,Stack}</c>
      when a run-time error occurs. See
      <seeguide marker="errors#exit_reasons">Exit Reasons</seeguide>.</p>
    <p>A process can terminate itself by calling one of the
       following BIFs:</p>
    <list type="bulleted">
      <item><c>exit(Reason)</c></item>
      <item><c>erlang:error(Reason)</c></item>
      <item><c>erlang:error(Reason, Args)</c></item>
    </list>
    <p>The process then terminates with reason <c>Reason</c> for
      <c>exit/1</c> or <c>{Reason,Stack}</c> for the others.</p>
    <p>A process can also be terminated if it receives an exit signal
      with another exit reason than <c>normal</c>, see
      <seeguide marker="#errors">Error Handling</seeguide>.</p>
  </section>

  <section>
    <title>Message Sending</title>
    <p>Processes communicate by sending and receiving messages.
      Messages are sent by using
      the <seeguide marker="expressions#send">send operator !</seeguide>
      and received by calling
      <seeguide marker="expressions#receive">receive</seeguide>.</p>
    <p>Message sending is asynchronous and safe, the message is
      guaranteed to eventually reach the recipient, provided that
      the recipient exists.</p>
  </section>

  <section>
    <title>Links</title>
    <p>
      Two processes can be <em>linked</em> to each other. Also a
      process and a port that resides on the same node can be linked
      to each other. A link beteen two processes can be created
      if one of them calls the
      <seemfa marker="erts:erlang#link/1"><c>link/1</c></seemfa> BIF
      with the process identifier of the other process as argument.
      Links can also be created using one the following spawn BIFs
      <seemfa marker="erts:erlang#spawn_link/4"><c>spawn_link()</c></seemfa>,
      <seemfa marker="erts:erlang#spawn_opt/5"><c>spawn_opt()</c></seemfa>, or
      <seemfa marker="erts:erlang#spawn_request/5"><c>spawn_request()</c></seemfa>.
      The spawn operation and the link operation will in these cases
      be performed atomically.
    </p>
    <p>
      If one of the participants of a link terminates, it will
      <seeguide marker="system/reference_manual:processes#sending_exit_signals">send
      an exit signal</seeguide> to the other participant. The exit
      signal will contain the
      <seeguide marker="system/reference_manual:processes#link_exit_signal_reason">exit
      reason</seeguide> of the terminated participant.
    </p>
    <p>
      A link can be removed by calling the
      <seemfa marker="erts:erlang#unlink/1"><c>unlink/1</c></seemfa>
      BIF.
    </p>
    <p>
      Links are bidirectional and there can only be one link between
      two processes. Repeated calls to <c>link()</c> have no effect.
      Either one of the involved processes may create or remove a
      link.
    </p>
    <p>Links are used to monitor the behaviour of other processes, see
      <seeguide marker="#errors">Error Handling</seeguide>.</p>
  </section>

  <section>
    <marker id="errors"></marker>
    <title>Error Handling</title>
    <p>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.</p>
    <p>See <seeguide marker="system/design_principles:des_princ#otp design principles">
      OTP Design Principles</seeguide> for more information about
      OTP supervision trees, which use this feature.</p>

    <section>
      <marker id="sending_exit_signals"/>
      <title>Sending Exit Signals</title>
      <p>
	When a process or port
	<seeguide marker="#term">terminates</seeguide> it will
	send exit signals to all processes and ports that it
	is <seeguide marker="#links">linked</seeguide> to.
	The exit signal will contain the following information:
      </p>
      <taglist>
	<tag>Sender identifier</tag>
	<item><p>
	  The process or port identifier of the process or port
	  that terminated.
	</p></item>
	<tag>Receiver identifier</tag>
	<item><p>
	  The process or port identifier of the process or port
	  which the exit signal is sent to.
	</p></item>
	<tag>The <c>link</c> flag</tag>
	<item><p>
	  This flag will be set indicating that the exit signal
	  was sent due to a link.
	</p></item>
	<tag><marker id="link_exit_signal_reason"/>Exit reason</tag>
	<item><p>
	  The exit reason of the process or port that
	  terminated or the atom:</p>
	  <list>
	    <item><p>
	      <c>noproc</c> in case no process or port was
	      found when setting up a link in a preceeding
	      call to the
	      <seemfa marker="erts:erlang#link/1"><c>link(PidOrPort)</c></seemfa>
	      BIF. The process or port identified as sender
	      of the exit signal will equal the <c>PidOrPort</c>
	      argument passed to <c>link/1</c>.
	    </p></item>
	    <item><p>
	      <c>noconnection</c> in case the linked
	      processes resides on different nodes and
	      the connection between the nodes was lost or
	      could not be established. The process or port
	      identified as sender of the exit signal might
	      in this case still be alive.
	    </p></item>
	  </list>
	</item>
      </taglist>
      
      <p>
	Exit signals can also be sent explicitly by calling the
	<seemfa marker="erts:erlang#exit/2"><c>exit(PidOrPort,
	Reason)</c></seemfa> BIF. The exit signal is sent to the
	process or port identified by the <c>PidOrPort</c> argument.
	The exit signal sent will contain the following information:
      </p>
      <taglist>
	<tag>Sender identifier</tag>
	<item><p>
	  The process identifier of the process that called
	  <c>exit/2</c>.
	</p></item>
	<tag>Receiver identifier</tag>
	<item><p>
	  The process or port identifier of the process or port
	  which the exit signal is sent to.
	</p></item>
	<tag>The <c>link</c> flag</tag>
	<item><p>
	  This flag will not be set, indicating that this exit
	  signal was not sent due to a link.
	</p></item>
	<tag>Exit reason</tag>
	<item><p>
	  The term passed as <c>Reason</c> in the call to
	  <c>exit/2</c>. If <c>Reason</c> is the atom <c>kill</c>,
	  the receiver cannot
	  <seeerl marker="erts:erlang#process_flag_trap_exit">trap
	  the exit</seeerl> signal and will unconditionally
	  terminate when it receives the signal.
	</p></item>
      </taglist>
    </section>

    <section>
      <marker id="receiving_exit_signals"/>
      <title>Receiving Exit Signals</title>

      <p>What happens when a process receives an exit signal depends on:</p>
      <list>
	<item><p>
	  The <seeerl marker="erts:erlang#process_flag_trap_exit">trap exit</seeerl>
	  state of the receiver at the time when the exit signal is received.
	</p></item>
	<item><p>
	  The exit reason of the exit signal.
	</p></item>
	<item><p>
	  The sender of the exit signal.
	</p></item>
	<item><p>
	  The state of the <c>link</c> flag of the exit signal. If the
	  <c>link</c> flag is set, the exit signal was sent due to a
	  link; otherwise, the exit signal was sent by a call to the
	  <seemfa marker="erts:erlang#exit/2"><c>exit/2</c></seemfa> BIF.
	</p></item>
	<item><p>
	  If the <c>link</c> flag is set, what happens also depends on
	  whether the <seemfa marker="erts:erlang#unlink/1">link is still active
	  or not</seemfa> when the exit signal is received.
	</p></item>
      </list>

      <p>
	Based on the above states, the following will happen when an
	exit signal is received by a process:
      </p>
      <list>
	<item>
	  <p>The exit signal is silently dropped if:</p>
	  <list>
	    <item><p>
	      the <c>link</c> flag of the exit signal is set and
	      the corresponding link has been deactivated.
	    </p></item>
	    <item><p>
	      the exit reason of the exit signal is the atom <c>normal</c>,
	      the receiver is not trapping exits, and the receiver and
	      sender are not the same process.
	    </p></item>
	  </list>
	</item>
	<item>
	  <p>The receiving process is terminated if:</p>
	  <list>
	    <item><p>
	      the <c>link</c> flag of the exit signal
	      is not set, and the exit reason of the exit signal
	      is the atom <c>kill</c>. The receiving process will
	      terminate with the atom <c>killed</c> as exit reason.
	    </p></item>
	    <item><p>
	      the receiver is not trapping exits, and the exit
	      reason is something other than the atom <c>normal</c>.
	      Also, if the <c>link</c> flag of the exit signal
	      is set, the link also needs to be active otherwise the
	      exit signal will be dropped. The exit reason of the
	      receiving process will equal the exit reason of the
	      exit signal. Note that if the <c>link</c> flag
	      is set, an exit reason of <c>kill</c> will <em>not</em>
	      be converted to <c>killed</c>.
	    </p></item>
	    <item><p>
	      the exit reason of the exit signal is the atom
	      <c>normal</c> and the sender of the exit signal is
	      the same process as the receiver. The <c>link</c>
	      flag cannot be set in this case. The exit reason
	      of the receiving process will be the atom <c>normal</c>.
	    </p></item>
	  </list>
	</item>
	<item>
	  <p>
	    The exit signal is converted to a message signal and
	    moved into the message queue of the receiver, if the
	    receiver is trapping exits, the <c>link</c> flag
	    of the exit signal is:
	  </p>
	    <list>
	      <item><p>
		not set, and the exit reason of the signal is not
		the atom <c>kill</c>.
	      </p></item>
	      <item><p>
		set, and the corresponding link is active.
		Note that an exit reason of <c>kill</c> will
		<em>not</em> terminate the process in this
		case and it will not be converted to
		<c>killed</c>.
	      </p></item>
	    </list>
	    <p>
	      The converted message will be on the form
	      <c>{'EXIT', SenderID, Reason}</c> where <c>Reason</c>
	      equals the exit reason of the exit signal and
	      <c>SenderID</c> is the identifier of the process
	      or port that sent the exit signal.
	    </p>
	</item>
      </list>
    </section>
  </section>

  <section>
    <title>Monitors</title>
    <p>An alternative to links are <em>monitors</em>. A process
      <c>Pid1</c> can create a monitor for <c>Pid2</c> by calling
      the BIF <c>erlang:monitor(process, Pid2)</c>. The function returns
      a reference <c>Ref</c>.</p>
    <p>If <c>Pid2</c> terminates with exit reason <c>Reason</c>, a
      'DOWN' message is sent to <c>Pid1</c>:</p>
    <code type="none">
{'DOWN', Ref, process, Pid2, Reason}</code>
    <p>If <c>Pid2</c> does not exist, the 'DOWN' message is sent
      immediately with <c>Reason</c> set to <c>noproc</c>.</p>
    <p>Monitors are unidirectional. Repeated calls to
      <c>erlang:monitor(process, Pid)</c> creates several
      independent monitors, and each one sends a 'DOWN' message when
      <c>Pid</c> terminates.</p>
    <p>A monitor can be removed by calling
      <c>erlang:demonitor(Ref)</c>.</p>
    <p>Monitors can be created for processes with registered
      names, also at other nodes.</p>
  </section>

  <section>
    <title>Process Dictionary</title>
    <p>Each process has its own process dictionary, accessed by calling
      the following BIFs:</p>
    <pre>
put(Key, Value)
get(Key)
get()
get_keys(Value)
erase(Key)
erase()</pre>
  </section>
</chapter>