I'm using spawn_link but doesn't understand its behavior. Consider the following code:
-module(test).
-export([try_spawn_link/0]).
try_spawn_link() ->
spawn(fun() ->
io:format("parent: ~p~n", [Parent = self()]),
Client = spawn_link(fun() ->
io:format("child: ~p~n", [self()]),
spawn_link_loop(Parent)
end),
spawn_link_loop(Client)
end).
spawn_link_loop(Peer) ->
receive
quit ->
exit(normal);
Any ->
io:format("~p receives ~p~n", [self(), Any])
end,
spawn_link_loop(Peer).
From the Erlang documentation, a link is created between the calling process and the new process, atomically. However, I tested as follows and didn't notice the effect of the link.
1> test:try_spawn_link().
parent: <0.34.0>
<0.34.0>
child: <0.35.0>
2> is_process_alive(pid(0,34,0)).
true
3> is_process_alive(pid(0,35,0)).
true
4> pid(0,35,0) ! quit.
quit
5> is_process_alive(pid(0,35,0)).
false
6> is_process_alive(pid(0,34,0)).
true
1> test:try_spawn_link().
parent: <0.34.0>
<0.34.0>
child: <0.35.0>
2> is_process_alive(pid(0,34,0)).
true
3> is_process_alive(pid(0,35,0)).
true
4> pid(0,34,0) ! quit.
quit
5> is_process_alive(pid(0,35,0)).
true
6> is_process_alive(pid(0,34,0)).
false
In my understanding, if one peer of the link exits, the other peer exits (or is notified to exit). But the results seem different from my understanding.
EDIT: thanks to the answers of legoscia and Pascal.
It is because you have chosen to use exit(normal). In this case the other process will not stop. If you use for example exit(killed) then you will get the behavior you are expecting.
You can use monitor to get informed about normal termination.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With