死んだはずのプロセスからメッセージが届く

『プログラミングErlang』8章に載っている on_exit/2 を使うと、既に死んでいるプロセスから死亡通知メッセージが届く、ように見える。

1> Foo = fun() -> 1 end.
#Fun<erl_eval.20.67289768>
2> Pid = spawn(Foo).
<0.33.0>
3> erlang:is_process_alive(Pid).
false
4> lib_misc:on_exit(Pid, fun(Why) -> io:format("~p dead with:~p~n", [Pid, Why]) end).
<0.33.0> dead with:noproc
<0.36.0>

これは erlang:link/1 の性質によるもの。man erlang より引用。

* If the calling process is not trapping exits, and checking Pid is cheap — that is, if Pid is local — link/1
fails with reason noproc.

* Otherwise, if the calling process is trapping exits, and/or Pid is remote, link/1 returns true, but an exit sig-
nal with reason noproc is sent to the calling process.

link/1の呼び出し自体は成功する、すなわち正常にリンクが確立できたように見える、というところがポイント。

この性質のせいで 9.8 の「キープアライブプロセス」の説明がおかしなことになっている。理解するのに丸一日かかったよ……。

One Response

  1. [...] なぜこのような動作になるかと言うと、システムプロセスが既に死んだプロセスに対して link すると、’noproc’ を原因として死んだかのような死亡通知メッセージが届くからだ(詳しくは以前の日記を参照)。 [...]

Leave a Reply