2

使用spawn_linkしていますが、その動作がわかりません。次のコードを検討してください。

-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).

Erlang ドキュメントから、リンクは呼び出しプロセスと新しいプロセスの間にアトミックに作成されます。ただし、次のようにテストしたところ、リンクの効果に気づきませんでした。

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

私の理解では、リンクの一方のピアが終了すると、もう一方のピアが終了します(または終了するように通知されます)。しかし、結果は私の理解とは異なるようです。

編集: legosciaPascalの回答に感謝します。

4

2 に答える 2

5

を使用することを選択したためexit(normal)です。この場合、他のプロセスは停止しません。たとえばexit(killed)、を使用すると、期待どおりの動作が得られます。

モニターを使用して、正常終了について通知を受けることができます。

于 2012-10-22T09:14:56.117 に答える
4

Erlang リファレンス マニュアルのプロセスの章の「エラー処理」セクションで説明されているように、リンクされたプロセスが終了すると、終了理由が ではない場合にのみ、リンクされたプロセスが終了しますnormal。これが、OTP がshutdown終了理由を広く使用する理由です。

于 2012-10-22T09:15:05.490 に答える