给定两个链接的进程child
和parent
,进程如何child
检测到parent
正常退出(终止)?
我,作为一个绝对的 Erlang 初学者,认为一个进程,当它无事可做时,使用exit(normal)
. 然后,这会向所有链接的进程发出信号,其中
- 已
trap_exit
设置为的进程的行为false
是忽略信号,并且 - 已
trap_exit
设置为的进程的行为true
是生成消息{'EXIT', pid, normal}
,其中pid
是终止进程的进程 ID。
我这么认为的原因是Learn You Some Erlang for Great Good和Erlang 文档,其中说明了以下内容。
如果退出原因是原子正常,则称进程正常终止。没有更多代码可以执行的进程正常终止。
显然这是错误的 (?),因为exit(normal
) 显示** exception exit: normal
在命令提示符中并使下面的代码工作。因为没有更多代码要执行而退出不会产生异常并且不会使我的代码工作。
例如,考虑以下代码。
-module(test).
-export([start/0,test/0]).
start() ->
io:format("Parent (~p): started!\n",[self()]),
P = spawn_link(?MODULE,test,[]),
io:format(
"Parent (~p): child ~p spawned. Waiting for 5 seconds\n",[self(),P]),
timer:sleep(5000),
io:format("Parent (~p): dies out of boredom\n",[self()]),
ok.
test() ->
io:format("Child (~p): I'm... alive!\n",[self()]),
process_flag(trap_exit, true),
loop().
loop() ->
receive
Q = {'EXIT',_,_} ->
io:format("Child process died together with parent (~p)\n",[Q]);
Q ->
io:format("Something else happened... (~p)\n",[Q])
after
2000 -> io:format("Child (~p): still alive...\n", [self()]), loop()
end.
这会产生如下输出。
(erlide@127.0.0.1)> test:start().
Parent (<0.145.0>): started!
Parent (<0.145.0>): child <0.176.0> spawned. Waiting for 5 seconds
Child (<0.176.0>): I'm... alive!
Child (<0.176.0>): still alive...
Child (<0.176.0>): still alive...
Parent (<0.145.0>): dies out of boredom
ok
(erlide@127.0.0.1)10> Child (<0.176.0>): still alive...
Child (<0.176.0>): still alive...
Child (<0.176.0>): still alive...
Child (<0.176.0>): still alive...
Child (<0.176.0>): still alive...
Child (<0.176.0>): still alive...
Child (<0.176.0>): still alive...
exit(pid(0,176,0),something).
Child process died together with parent ({'EXIT',<0.194.0>,something})
如果必须手动执行exit(pid(0,176,0),something)
命令以防止孩子永远活着。更改ok.
为start
使exit(normal)
执行像这样进行
(erlide@127.0.0.1)3> test:start().
Parent (<0.88.0>): started!
Parent (<0.88.0>): child <0.114.0> spawned. Waiting for 5 seconds
Child (<0.114.0>): I'm... alive!
Child (<0.114.0>): still alive...
Child (<0.114.0>): still alive...
Parent (<0.88.0>): dies out of boredom
Child process died together with parent ({'EXIT',<0.88.0>,normal})
** exception exit: normal
我的具体问题如下。
- 如何使上述代码按预期工作。也就是说,如何在不更改父进程的情况下确保子进程与父进程一起死亡?
- 为什么会在 CLI中
exit(normal)
生成一个?** exception exit: normal
我很难将异常视为正常现象。Erlang 文档中的气味是什么意思?
我认为这些一定是非常基本的问题,但我似乎无法弄清楚......我在 Windows (x64) 上使用 Erlang 5.9.3.1。