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
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
|
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE chapter SYSTEM "chapter.dtd">
<chapter>
<header>
<copyright>
<year>2003</year><year>2023</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 different <c>spawn</c> BIFs:</p>
<list>
<item><seemfa marker="erts:erlang#spawn/4"><c>spawn/1,2,3,4</c></seemfa></item>
<item><seemfa marker="erts:erlang#spawn_link/4"><c>spawn_link/1,2,3,4</c></seemfa></item>
<item><seemfa marker="erts:erlang#spawn_monitor/4"><c>spawn_monitor/1,2,3,4</c></seemfa></item>
<item><seemfa marker="erts:erlang#spawn_opt/5"><c>spawn_opt/2,3,4,5</c></seemfa></item>
<item><seemfa marker="erts:erlang#spawn_request/5"><c>spawn_request/1,2,3,4,5</c></seemfa></item>
</list>
</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>
<title>Process Aliases</title>
<p>
When sending a message to a process, the receiving process can be
identified by a <seeguide marker="data_types#pid">PID</seeguide>,
a <seeguide marker="#registered-processes">registered name</seeguide>,
or a <i>process alias</i> which is a term of the type
<seeguide marker="data_types#reference">reference</seeguide>.
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.
</p>
<p>
A process alias can be used as identifier of the receiver when
sending a message using the
<seeguide marker="expressions#send">send operator <c>!</c></seeguide> or
send BIFs such as
<seemfa marker="erts:erlang#send/2"><c>erlang:send/2</c></seemfa>.
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
<em>not</em> be removed.
</p>
<p>
A process alias is created either by calling one of the
<seemfa marker="erts:erlang#alias/0"><c>alias/0,1</c></seemfa>
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
<c>{alias, _}</c> option to the
<seemfa marker="erts:erlang#monitor/3"><c>monitor/3</c></seemfa>
BIF. The <c>{alias, _}</c> option can also be passed when
creating a monitor via
<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>.
</p>
<p>
A process alias can be deactivated by the process that created it
by calling the
<seemfa marker="erts:erlang#unalias/1"><c>unalias/1</c></seemfa> BIF.
It is also possible to automatically deactivate an alias on
certain events. See the documentation of the
<seemfa marker="erts:erlang#alias/1"><c>alias/1</c></seemfa> BIF,
and the <c>{alias, _}</c> option of the
<seemfa marker="erts:erlang#monitor/3"><c>monitor/3</c></seemfa> BIF
for more information about automatic deactivation of aliases.
</p>
<p>
It is <em>not</em> possible to:
</p>
<list>
<item>create an alias identifying another process than the caller.</item>
<item>deactivate an alias unless it identifies the caller.</item>
<item>look up an alias.</item>
<item>look up the process identified by an alias.</item>
<item>check if an alias is active or not.</item>
<item>check if a reference is an alias.</item>
</list>
<p>
These are all intentional design decisions relating to
performance, scalability, and distribution transparency.
</p>
</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>Signals</title>
<p>
<marker id="message-sending"/>
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
<seeguide marker="expressions#send">send operator <c>!</c></seeguide>.
A received message can be fetched from the message queue by the
receiving process using the
<seeguide marker="expressions#receive"><c>receive</c></seeguide>
expression.
</p>
<marker id="sync-comm"/>
<p>
Synchronous communication can be broken down into multiple asynchronous
signals. An example of such a synchronous communication is a call to the
<seemfa marker="erts:erlang#process_info/2"><c>erlang:process_info/2</c></seemfa>
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.
</p>
<section>
<title>Sending Signals</title>
<p>
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.
</p>
<taglist>
<tag><c>message</c></tag>
<item>
Sent when using the
<seeguide marker="expressions#send">send operator <c>!</c></seeguide>,
or when calling one of the
<seemfa marker="erts:erlang#send/2"><c>erlang:send/2,3</c></seemfa>
or
<seemfa marker="erts:erlang#send_nosuspend/2"><c>erlang:send_nosuspend/2,3</c></seemfa>
BIFs.
</item>
<tag><c>link</c></tag>
<item>
Sent when calling the
<seemfa marker="erts:erlang#link/1">link/1</seemfa> BIF.
</item>
<tag><c>unlink</c></tag>
<item>
Sent when calling the
<seemfa marker="erts:erlang#unlink/1">unlink/1</seemfa> BIF.
</item>
<tag><c>exit</c></tag>
<item>
Sent either when explicitly sending an <c>exit</c> signal by
calling the
<seemfa marker="erts:erlang#exit/2">exit/2</seemfa> BIF, or when
a <seeguide marker="#sending_exit_signals">linked process
terminates</seeguide>. If the signal is sent due to a link, the
signal is sent after all <seeguide marker="#visible-resources">
<i>directly visible Erlang resources</i></seeguide> used by the
process have been released.
</item>
<tag><c>monitor</c></tag>
<item>
Sent when calling one of the
<seemfa marker="erts:erlang#monitor/3">monitor/2,3</seemfa> BIFs.
</item>
<tag><c>demonitor</c></tag>
<item>
Sent when calling one of the
<seemfa marker="erts:erlang#demonitor/1">demonitor/1,2</seemfa>
BIFs, or when a process monitoring another process terminates.
</item>
<tag><c>down</c></tag>
<item>
Sent by a <seeguide marker="#monitors">monitored process or
port that terminates</seeguide>. The signal is sent after
all <seeguide marker="#visible-resources"><i>directly visible
Erlang resources</i></seeguide> used by the process or the port
have been released.
</item>
<tag><c>change</c></tag>
<item>
Sent by the <seeguide marker="#runtime-service">clock
service</seeguide> on the local runtime system, when the
<seemfa marker="erts:erlang#time_offset/0">time offset</seemfa>
changes, to processes which have
<seemfa marker="erts:erlang#monitor/2">monitored the
<c>time_offset</c></seemfa>.
</item>
<tag><c>group_leader</c></tag>
<item>
Sent when calling the
<seemfa marker="erts:erlang#group_leader/2">group_leader/2</seemfa>
BIF.
</item>
<tag>
<c>spawn_request</c>/<c>spawn_reply</c>,
<c>open_port_request</c>/<c>open_port_reply</c>
</tag>
<item>
Sent due to a call to one of the
<seemfa marker="erts:erlang#spawn/4"><c>spawn/1,2,3,4</c></seemfa>,
<seemfa marker="erts:erlang#spawn_link/4"><c>spawn_link/1,2,3,4</c></seemfa>,
<seemfa marker="erts:erlang#spawn_monitor/4"><c>spawn_monitor/1,2,3,4</c></seemfa>,
<seemfa marker="erts:erlang#spawn_opt/5"><c>spawn_opt/2,3,4,5</c></seemfa>,
<seemfa marker="erts:erlang#spawn_request/5"><c>spawn_request/1,2,3,4,5</c></seemfa>,
or <seemfa marker="erts:erlang#open_port/2"><c>erlang:open_port/2</c></seemfa>
BIFs. The request signal is sent to the
<seeguide marker="#runtime-service">spawn service</seeguide> which
responds with the reply signal.
</item>
<tag><c>alive_request</c>/<c>alive_reply</c></tag>
<item>
Sent due to a call to the
<seemfa marker="erts:erlang#is_process_alive/1">is_process_alive/1</seemfa>
BIF.
</item>
<tag>
<c>garbage_collect_request</c>/<c>garbage_collect_reply</c>,
<c>check_process_code_request</c>/<c>check_process_code_reply</c>,
<c>process_info_request</c>/<c>process_info_reply</c>
</tag>
<item>
Sent due to a call to one of the
<seemfa marker="erts:erlang#garbage_collect/1">garbage_collect/1,2</seemfa>,
<seemfa marker="erts:erlang#check_process_code/2">erlang:check_process_code/2,3</seemfa>,
or <seemfa marker="erts:erlang#process_info/2">process_info/1,2</seemfa>
BIFs. Note that if the request is directed towards the caller itself
and it is a synchronous request, no signaling will be performed
and the caller will instead synchronously perform the request before
returning from the BIF.
</item>
<tag><c>port_command</c>, <c>port_connect</c>, <c>port_close</c></tag>
<item>
Sent by a process to a port on the local node using the
<seeguide marker="expressions#send">send operator <c>!</c></seeguide>,
or by calling one of the
<seemfa marker="erts:erlang#send/2"><c>send()</c></seemfa>
BIFs. The signal is sent by passing a term on the format
<c>{Owner, {command, Data}}</c>, <c>{Owner, {connect, Pid}}</c>,
or <c>{Owner, close}</c> as message.
</item>
<tag>
<c>port_command_request</c>/<c>port_command_reply</c>,
<c>port_connect_request</c>/<c>port_connect_reply</c>,
<c>port_close_request</c>/<c>port_close_reply</c>,
<c>port_control_request</c>/<c>port_control_reply</c>,
<c>port_call_request</c>/<c>port_call_reply</c>,
<c>port_info_request</c>/<c>port_info_reply</c>
</tag>
<item>
Sent due to a call to one of the
<seemfa marker="erts:erlang#port_command/2"><c>erlang:port_command/2,3</c></seemfa>,
<seemfa marker="erts:erlang#port_connect/2"><c>erlang:port_connect/2</c></seemfa>,
<seemfa marker="erts:erlang#port_close/1"><c>erlang:port_close/1</c></seemfa>,
<seemfa marker="erts:erlang#port_control/3"><c>erlang:port_control/3</c></seemfa>,
<seemfa marker="erts:erlang#port_call/3"><c>erlang:port_call/3</c></seemfa>,
<seemfa marker="erts:erlang#port_info/1"><c>erlang:port_info/1,2</c></seemfa>
BIFs. The request signal is sent to a port on the local node which
responds with the reply signal.
</item>
<tag>
<c>register_name_request</c>/<c>register_name_reply</c>,
<c>unregister_name_request</c>/<c>unregister_name_reply</c>,
<c>whereis_name_request</c>/<c>whereis_name_reply</c>
</tag>
<item>
Sent due to a call to one of the
<seemfa marker="erts:erlang#register/2"><c>register/2</c></seemfa>,
<seemfa marker="erts:erlang#unregister/1"><c>unregister/1</c></seemfa>,
or
<seemfa marker="erts:erlang#whereis/1"><c>whereis/1</c></seemfa>
BIFs. The request signal is sent to the
<seeguide marker="#runtime-service">name service</seeguide>, which
responds with the reply signal.
</item>
<tag>
<c>timer_start_request</c>/<c>timer_start_reply</c>,
<c>timer_cancel_request</c>/<c>timer_cancel_reply</c>
</tag>
<item>
Sent due to a call to one of the
<seemfa marker="erts:erlang#send_after/3"><c>erlang:send_after/3,4</c></seemfa>,
<seemfa marker="erts:erlang#start_timer/3"><c>erlang:start_timer/3,4</c></seemfa>,
or
<seemfa marker="erts:erlang#cancel_timer/1"><c>erlang:cancel_timer/1,2</c></seemfa>
BIFs. The request signal is sent to the
<seeguide marker="#runtime-service">timer service</seeguide> which
responds with the reply signal.
</item>
</taglist>
<p><marker id="runtime-service"/>
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 <em>not</em> preserved. Note
that this does <em>not</em> violate the
<seeguide marker="#signal-delivery">signal ordering
guarantee</seeguide> of the language.
</p>
<p>
The realization of the signals described above may change both at
runtime and due to changes in implementation. You may be able to
detect such changes using <c>receive</c> tracing or by inspecting
message queues. However, these are internal implementation details of
the runtime system that you should <em>not</em> rely on. As an example,
many of the reply signals above 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.
</p>
</section>
<section>
<title>Receiving Signals</title>
<p>
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 <em>not</em> tied to the
execution of a
<seeguide marker="expressions#receive"><c>receive</c></seeguide>
expression, but can happen anywhere in the execution flow of a process.
</p>
<p>
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:
</p>
<taglist>
<tag><c>message</c></tag>
<item>
If the message signal was sent using a
<seeguide marker="#process-aliases">process alias</seeguide>
that is no longer active, the message signal will be dropped;
otherwise, if the alias is still active or the message signal
was sent by other means, the message is added to the end of the
message queue. When the message has been added to the message
queue, the receiving process can fetch the message from the
message queue using the
<seeguide marker="expressions#receive"><c>receive</c></seeguide>
expression.
</item>
<tag><c>link</c>, <c>unlink</c></tag>
<item>
Very simplified it can be viewed as updating process local
information about the link. A detailed description of the
<seeguide marker="erts:erl_dist_protocol#link_protocol">link
protocol</seeguide> can be found in the <i>Distribution Protocol</i>
chapter of the <i>ERTS User's Guide</i>.
</item>
<tag><c>exit</c></tag>
<item>
Set the receiver in an exiting state, drop the signal, or convert
the signal into a message and add it to the end of the message
queue. If the receiver is set in an exiting state, no more Erlang
code will be executed and the process is scheduled for termination.
The section <seeguide marker="#receiving_exit_signals"><i>Receiving
Exit Signals</i></seeguide> below gives more details on the
action taken when an <c>exit</c> signal is received.
</item>
<tag><c>monitor</c>, <c>demonitor</c></tag>
<item>
Update process local information about the monitor.
</item>
<tag><c>down</c>, <c>change</c></tag>
<item>
Convert into a message if the corresponding monitor is still
active; otherwise, drop the signal. If the signal is converted
into a message, it is also added to the end of the message
queue.
</item>
<tag><c>group_leader</c></tag>
<item>
Change the group leader of the process.
</item>
<tag><c>spawn_reply</c></tag>
<item>
Convert into a message, or drop the signal depending on the reply
and how the <c>spawn_request</c> signal was configured. If the
signal is converted into a message it is also added to the end
of the message queue. For more information see the
<seemfa marker="erts:erlang#spawn_request/5"><c>spawn_request()</c></seemfa>
BIF.
</item>
<tag><c>alive_request</c></tag>
<item>
Schedule execution of the <i>is alive</i> test. If the process
is in an exiting state, the <i>is alive</i> test will not be
executed until after all
<seeguide marker="#visible-resources"><i>directly visible Erlang
resources</i></seeguide> used by the process have been released.
The <c>alive_reply</c> will be sent after the <i>is alive</i>
test has executed.
</item>
<tag>
<c>process_info_request</c>,
<c>garbage_collect_request</c>,
<c>check_process_code_request</c>
</tag>
<item>
Schedule execution of the requested operation. The reply signal
will be sent when the operation has been executed.
</item>
</taglist>
<p>
Note that some actions taken when a signal is received involves
<em>scheduling</em> 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, <em>not</em> violate the
<seeguide marker="#signal-delivery">signal ordering
guarantee</seeguide> of the language.
</p>
<marker id="message-queue-order"/>
<p>
The order of messages in the message queue of a process reflects the
order in which the signals corresponding to the messages has been
received since <seeguide marker="processes#receiving-signals">all
signals that add messages to the message queue add them at the end of
the message queue</seeguide>. Messages corresponding to signals from
the same sender are also ordered in the same order as the signals were
sent due to the <seeguide marker="processes#signal-delivery">signal
ordering guarantee</seeguide> of the language.
</p>
</section>
<section>
<marker id="visible-resources"/>
<title>Directly Visible Erlang Resources</title>
<p>
As described above, <c>exit</c> signals due to links, <c>down</c>
signals, and reply signals from an exiting process due to
<c>alive_request</c>s are not sent until all <i>directly visible
Erlang resources</i> held by the terminating process have been
released. With <i>directly visible Erlang resources</i> 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 <i>directly visible Erlang
resources</i> are <seeguide marker="#registered-processes">registered
name</seeguide> and <seeerl marker="stdlib:ets">ETS</seeerl> tables.
</p>
<section>
<title>The Excluded Resources</title>
<p>
The process identifier of the process cannot be released for
reuse until everything regarding the process has been released.
</p>
<p>
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. <i>Directly visible Erlang
resources</i> 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 effecting
other processes by, for example, disabling functionality such as
<seecref marker="erts:erl_nif#enif_send"><c>enif_send()</c></seecref>
when used from a terminated process, but if the NIF is not well
behaved it can still effect other processes. A well behaved dirty
NIF should test if
<seecref marker="erts:erl_nif#enif_is_current_process_alive">the
process it is executing in has exited</seecref>, and if so stop
executing.
</p>
<p>
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
<seecref marker="erts:erl_nif#resource_objects">resource
objects</seecref> on the heap.
</p>
</section>
</section>
<section>
<marker id="signal-delivery"/>
<title>Delivery of Signals</title>
<p>
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 <c>link</c> signal
sent to a non-existing process triggers an <c>exit</c> signal, which
is sent back to where the <c>link</c> signal originated from. When
communicating over the distribution, signals can be lost if the
distribution channel goes down.
</p>
<p>
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 <c>A</c> sends a signal <c>S1</c> to
<c>B</c>, and later sends signal <c>S2</c> to <c>B</c>, <c>S1</c> is
guaranteed not to arrive after <c>S2</c>. Note that <c>S1</c> may,
or may not have been lost.
</p>
</section>
<section>
<marker id="signal-irregularities"/>
<title>Irregularities</title>
<taglist>
<tag>Synchronous Error Checking</tag>
<item>
<p>
Some functionality that send signals have synchronous error
checking when sending locally on a node and fail if the receiver
is not present at the time when the signal is sent:
</p>
<list>
<item>
The <seeguide marker="expressions#send">send operator
<c>!</c></seeguide>,
<seemfa marker="erts:erlang#send/2"><c>erlang:send/2,3</c></seemfa>,
BIFs and
<seemfa marker="erts:erlang#send_nosuspend/2"><c>erlang:send_nosuspend/2,3</c></seemfa>
BIFs when the receiver is identified by a name that is
expected to be registered locally.
</item>
<item>
<seemfa marker="erts:erlang#link/1"><c>erlang:link/1</c></seemfa>
</item>
<item>
<seemfa marker="erts:erlang#group_leader/2"><c>erlang:group_leader/2</c></seemfa>
</item>
</list>
<p></p>
</item>
<tag>Unexpected Behaviours of Exit Signals</tag>
<item>
<p>
When a process sends an exit signal with exit reason <c>normal</c>
to itself by calling <seemfa marker="erts:erlang#exit/2"><c>erlang:exit(self(),
normal)</c></seemfa> it will be terminated
<seeguide marker="#receiving_exit_signals">when the <c>exit</c> signal
is received</seeguide>. In all other cases when an exit signal with
exit reason <c>normal</c> is received, it is dropped.
</p>
<p>
When an <seeguide marker="#receiving_exit_signals"><c>exit</c> signal
with exit reason <c>kill</c> is received</seeguide>,
the action taken is different depending on whether the signal was
sent due to a linked process terminating, or the signal was
explicitly sent using the
<seemfa marker="erts:erlang#exit/2"><c>exit/2</c></seemfa> BIF. When
sent using the <c>exit/2</c> BIF, the signal cannot be
<seeerl marker="erts:erlang#process_flag_trap_exit">trapped</seeerl>,
while it can be trapped if the signal was sent due to a link.
</p>
</item>
<tag>Blocking Signaling Over Distribution</tag>
<item>
<p>
When sending a signal over a distribution channel, the sending
process may be suspended even though the signal is supposed to be
sent asynchronously. This is due to the built in flow control over
the channel that has been present more or less for ever. When the
size of the output buffer for the channel reach the <i>distribution
buffer busy limit</i>, processes sending on the channel will be
suspended until the size of the buffer shrinks below the limit.
The size of the limit can be inspected by calling
<seeerl marker="erts:erlang#system_info_dist_buf_busy_limit">
<c>erlang:system_info(dist_buf_busy_limit)</c></seeerl>.
Since this functionality has been present for so long, it is not
possible to remove it, but it is possible to increase the limit
to a point where it more or less never is reached using the
<c>erl</c> command line argument
<seecom marker="erts:erl#+zdbbl"><c>+zdbbl</c></seecom>. Note
that if you do raise the limit like this, you need to take care
of flow control yourself to ensure that you do not get into a
situation with excessive memory usage. As of OTP 25.3 it is
also possible to enable <i>fully asynchronous distributed
signaling</i> on a per process level using
<seeerl marker="erts:erlang#process_flag_async_dist">
<c>process_flag(async_dist, Bool)</c></seeerl>. Also in this case
you need to take care of flow control yourself.
</p>
</item>
</taglist>
<p>
The irregularities mentioned above cannot be fixed as they have been
part of Erlang too long and it would break a lot of existing code.
</p>
</section>
</section>
<section>
<title>Links</title>
<p>
Two processes can be <em>linked</em> 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
<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
be performed atomically, in these cases.
</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 behavior 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 preceding
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
added to the end of 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>
|