Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

spawn_link not working?

Tags:

erlang

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.

like image 557
Xiao Jia Avatar asked Mar 06 '26 06:03

Xiao Jia


1 Answers

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.

like image 114
Pascal Avatar answered Mar 10 '26 16:03

Pascal



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!