我有一些C代码,我正在使用Erlang的端口功能作为外部进程执行.我希望启动C代码的进程通过open_port检测C代码是否崩溃.文档对我来说并不完全清楚,但据我了解,在Erlang进程和外部代码之间建立了双向链接.如果一个人死亡,另一个人会收到通知.
以下是"Erlang互操作性教程指南"(http://www.erlang.org/doc/tutorial/c_port.html)中代码的略微修改版本:
init(ExtPrg) ->
register(cport, self()),
process_flag(trap_exit, true),
Port = open_port({spawn, ExtPrg}, [{packet, 2}]),
PInfo = erlang:port_info(Port),
io:format("Port: ~p PInfo: ~p~n", [Port, PInfo]),
RVal = link(Port),
io:format("link? ~p~n", [RVal]),
loop(Port).
loop(Port) ->
receive
{call, Caller, Msg} ->
Port ! {self(), {command, encode(Msg)}},
receive
{Port, {data, Data}} ->
Caller ! {cport, decode(Data)}
end,
loop(Port);
stop ->
Port ! {self(), close},
receive
{Port, closed} ->
exit(normal)
end;
{'EXIT', Port, Reason} ->
exit(port_terminated)
end.
Run Code Online (Sandbox Code Playgroud)
该init呼叫正确执行的C代码,并且你可以看到套trap_exit,但是EXTT当我杀使用C代码没有收到消息kill -HUP从Unix外壳.我已尝试使用和不使用link调用(Erlang文档不使用它).我添加的打印代码生成:
Eshell V5.9.1 (abort with ^G)
1> cport:start("./cport 22").
Port: #Port<0.630> PInfo: [{name,"./cport 22"},
{links,[<0.38.0>]},
{id,630},
{connected,<0.38.0>},
{input,0},
{output,0}]
<0.38.0>
link? true
Run Code Online (Sandbox Code Playgroud)
似乎链接已注册,但我没有抓住陷阱.我错过了什么?
调用open_port()时尝试额外的选项exit_status.
我做了类似的Erlang程序来监督游戏服务器.当外部游戏服务器崩溃时,我想从我的中央Erlang监控系统重新启动它.这是对我有用的代码:
erlang:open_port({spawn_executable, "<Path to my game server start script>"},
[ exit_status ]),
Run Code Online (Sandbox Code Playgroud)
当外部进程被终止时,您将收到类型的消息
{Port,{exit_status,Status}}
Run Code Online (Sandbox Code Playgroud)