Erlang的open_port调用链接到生成的进程吗?

时间:2013-03-04 05:44:16

标签: erlang

我有一些C代码,我正在使用Erlang的端口功能作为外部进程执行。我希望通过open_port启动C代码的进程检测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.

init调用正确执行C代码,正如您可以看到集trap_exit,但是当我使用{{1}终止C代码时未收到EXTT消息来自Unix shell。我已经尝试过使用和不使用kill -HUP调用(Erlang文档不使用它)。我添加的打印代码生成:

link

似乎已注册一个链接,但我没有抓住陷阱。我错过了什么?

1 个答案:

答案 0 :(得分:5)

调用open_port()时尝试额外选项exit_status。

我做了类似的Erlang程序来监督游戏服务器。 当外部游戏服务器崩溃时,我想从我的中央Erlang监控系统重新启动它。 这是对我有用的代码:

erlang:open_port({spawn_executable, "<Path to my game server start script>"}, 
                 [ exit_status ]),

当外部进程被终止时,您将收到类型为

的消息
{Port,{exit_status,Status}}