我正在使用 Erlang 端口读取 Linux 进程的输出。我希望每当我连接的 Erlang 进程终止时,Linux 进程就会自动终止。从文档来看,在我看来这应该自动发生,但事实并非如此。
最小的例子。将其放入文件 test.erl 中:
-module(test).
-export([start/0, spawn/0]).
start() ->
Pid = spawn_link(?MODULE, spawn, []),
register(test, Pid).
spawn() ->
Port = open_port({spawn, "watch date"},[stream, exit_status]),
loop([{port, Port}]).
loop(State) ->
receive
die ->
error("died");
Any ->
io:fwrite("Received: ~p~n", [Any]),
loop(State)
end.
然后,在 erl shell 中:
1> c(test).
{ok,test}
2> test:start().
true
该进程启动并每 2 秒打印一些从 Linux“watch”命令接收到的数据。
然后,我让 Erlang 进程崩溃:
3> test ! die.
=ERROR REPORT==== 26-May-2021::13:24:01.057065 ===
Error in process <0.95.0> with exit value:
{"died",[{test,loop,1,[{file,"test.erl"},{line,15}]}]}
** exception exit: "died"
in function test:loop/1 (test.erl, line 15)
Erlang 进程按预期终止,来自“watch”的数据停止出现,但 watch 进程仍然在后台运行,如 Linux(不是 erl)终端中所示:
fuxoft@frantisek:~$ pidof watch
1880127
在我的现实场景中,我没有使用“watch”命令,而是使用其他输出数据且不接受输入的进程。当我连接的 Erlang 进程崩溃时,如何让它自动死亡?我可以使用 Erlang 管理程序来完成此操作,并在 Erlang 进程崩溃时手动发出“kill”命令,但我认为这可以更简单、更干净地完成。