Note that there are some explanatory texts on larger screens.

plurals
  1. POProcesses exiting normally
    primarykey
    data
    text
    <p>Given two linked processes <code>child</code> and <code>parent</code>, how does process <code>child</code> detect that <code>parent</code> exits (terminates) normally?</p> <p>I, as an absolute Erlang beginner, thought that a process, when it has nothing else to do, exited using <code>exit(normal)</code>. This then signals all linked processes, where</p> <ul> <li>the behaviour of processes that have <code>trap_exit</code> set to <code>false</code> is to ignore the signal, and</li> <li>the behaviour of processes that have <code>trap_exit</code> set to <code>true</code> is to generate the message <code>{'EXIT', pid, normal}</code> where <code>pid</code> is the process id of the terminating process. </li> </ul> <p>My reason for thinking this is <a href="http://learnyousomeerlang.com/errors-and-processes#its-a-trap" rel="nofollow">Learn You Some Erlang for Great Good</a> and the <a href="http://www.erlang.org/doc/reference_manual/processes.html" rel="nofollow">Erlang documentation</a> which states the following.</p> <blockquote> <p>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.</p> </blockquote> <p>Apparently that is wrong (?), because <code>exit(normal</code>) shows <code>** exception exit: normal</code> in the command prompt and makes the code below work. Exiting because there is no more code to execute does not generate the exception and does not make my code work.</p> <p>As an example, consider the following code.</p> <pre class="lang-erlang prettyprint-override"><code>-module(test). -export([start/0,test/0]). start() -&gt; io:format("Parent (~p): started!\n",[self()]), P = spawn_link(?MODULE,test,[]), io:format( "Parent (~p): child ~p spawned. Waiting for 5 seconds\n",[self(),P]), timer:sleep(5000), io:format("Parent (~p): dies out of boredom\n",[self()]), ok. test() -&gt; io:format("Child (~p): I'm... alive!\n",[self()]), process_flag(trap_exit, true), loop(). loop() -&gt; receive Q = {'EXIT',_,_} -&gt; io:format("Child process died together with parent (~p)\n",[Q]); Q -&gt; io:format("Something else happened... (~p)\n",[Q]) after 2000 -&gt; io:format("Child (~p): still alive...\n", [self()]), loop() end. </code></pre> <p>This produces output as follows.</p> <pre><code>(erlide@127.0.0.1)&gt; test:start(). Parent (&lt;0.145.0&gt;): started! Parent (&lt;0.145.0&gt;): child &lt;0.176.0&gt; spawned. Waiting for 5 seconds Child (&lt;0.176.0&gt;): I'm... alive! Child (&lt;0.176.0&gt;): still alive... Child (&lt;0.176.0&gt;): still alive... Parent (&lt;0.145.0&gt;): dies out of boredom ok (erlide@127.0.0.1)10&gt; Child (&lt;0.176.0&gt;): still alive... Child (&lt;0.176.0&gt;): still alive... Child (&lt;0.176.0&gt;): still alive... Child (&lt;0.176.0&gt;): still alive... Child (&lt;0.176.0&gt;): still alive... Child (&lt;0.176.0&gt;): still alive... Child (&lt;0.176.0&gt;): still alive... exit(pid(0,176,0),something). Child process died together with parent ({'EXIT',&lt;0.194.0&gt;,something}) </code></pre> <p>If had to manually execute the <code>exit(pid(0,176,0),something)</code> command to keep the child from staying alive forever. Changing <code>ok.</code> in <code>start</code> to <code>exit(normal)</code> makes the execution go like this</p> <pre><code>(erlide@127.0.0.1)3&gt; test:start(). Parent (&lt;0.88.0&gt;): started! Parent (&lt;0.88.0&gt;): child &lt;0.114.0&gt; spawned. Waiting for 5 seconds Child (&lt;0.114.0&gt;): I'm... alive! Child (&lt;0.114.0&gt;): still alive... Child (&lt;0.114.0&gt;): still alive... Parent (&lt;0.88.0&gt;): dies out of boredom Child process died together with parent ({'EXIT',&lt;0.88.0&gt;,normal}) ** exception exit: normal </code></pre> <p>My concrete questions are the following.</p> <ol> <li>How can I make the above code work as expected. That is, how can I make sure the child process dies together with the parent process <em>without changing the parent process</em>?</li> <li>Why does <code>exit(normal)</code> generate a <code>** exception exit: normal</code> in the CLI? It is hard for me to think of an exception as something that is normal. What does the scentence in the Erlang documentation mean?</li> </ol> <p>I think these must be extremely basic questions, but I can't seem to figure this out.... I am using Erlang 5.9.3.1 on Windows (x64).</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload