为什么 erlang shell 只从生成的进程中收到一次退出消息?
Why does erlang shell receive exit message from spawned processes only once?
代码如下:
Erlang/OTP 20 [erts-9.1] [source] [64-bit] [smp:2:2] [ds:2:2:10] [async-threads:10] [kernel-poll:false]
Eshell V9.1 (abort with ^G)
1> process_flag(trap_exit, true).
false
2> spawn_link(fun() -> exit(reason) end).
<0.63.0>
3> receive X -> X after 0 -> 'end' end.
{'EXIT',<0.63.0>,reason}
4> spawn_link(fun() -> exit(reason) end).
<0.66.0>
5> receive X -> X after 0 -> 'end' end.
'end'
为什么 erlang shell 没有收到来自第二个派生进程的退出消息?
在第一个 receive
成功后,X
绑定到它的返回值,即 {'EXIT', <...>, reason}
。由于您在第二个 receive
中使用了相同的变量 X
,因此 receive
等待与 X
的旧值完全匹配的消息,而这将不匹配第二个消息因为它的PID和第一个不同。
要解决此问题,您可以使用不同的变量名称:
1> process_flag(trap_exit, true).
false
2> spawn_link(fun() -> exit(reason) end).
<0.67.0>
3> receive X -> X after 0 -> 'end' end.
{'EXIT',<0.67.0>,reason}
4> X.
{'EXIT',<0.67.0>,reason}
5> spawn_link(fun() -> exit(reason) end).
<0.71.0>
6> receive X2 -> X2 after 0 -> 'end' end.
{'EXIT',<0.71.0>,reason}
或者你可以使用 f/1
"forget" X
的值,然后再次使用 X
(这只适用于 REPL):
7> spawn_link(fun() -> exit(reason) end).
<0.74.0>
8> f(X).
ok
9> receive X -> X after 0 -> 'end' end.
{'EXIT',<0.74.0>,reason}
代码如下:
Erlang/OTP 20 [erts-9.1] [source] [64-bit] [smp:2:2] [ds:2:2:10] [async-threads:10] [kernel-poll:false]
Eshell V9.1 (abort with ^G)
1> process_flag(trap_exit, true).
false
2> spawn_link(fun() -> exit(reason) end).
<0.63.0>
3> receive X -> X after 0 -> 'end' end.
{'EXIT',<0.63.0>,reason}
4> spawn_link(fun() -> exit(reason) end).
<0.66.0>
5> receive X -> X after 0 -> 'end' end.
'end'
为什么 erlang shell 没有收到来自第二个派生进程的退出消息?
在第一个 receive
成功后,X
绑定到它的返回值,即 {'EXIT', <...>, reason}
。由于您在第二个 receive
中使用了相同的变量 X
,因此 receive
等待与 X
的旧值完全匹配的消息,而这将不匹配第二个消息因为它的PID和第一个不同。
要解决此问题,您可以使用不同的变量名称:
1> process_flag(trap_exit, true).
false
2> spawn_link(fun() -> exit(reason) end).
<0.67.0>
3> receive X -> X after 0 -> 'end' end.
{'EXIT',<0.67.0>,reason}
4> X.
{'EXIT',<0.67.0>,reason}
5> spawn_link(fun() -> exit(reason) end).
<0.71.0>
6> receive X2 -> X2 after 0 -> 'end' end.
{'EXIT',<0.71.0>,reason}
或者你可以使用 f/1
"forget" X
的值,然后再次使用 X
(这只适用于 REPL):
7> spawn_link(fun() -> exit(reason) end).
<0.74.0>
8> f(X).
ok
9> receive X -> X after 0 -> 'end' end.
{'EXIT',<0.74.0>,reason}