4

我有一些 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.

init调用正确地执行了 C 代码,并且如您所见 sets trap_exit,但是当我使用Unix shell 终止EXTTC 代码时未收到该消息。kill -HUP我尝试过调用和不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

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

4

1 回答 1

6

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

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

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

当外部进程被杀死时,您将收到一条消息类型

{Port,{exit_status,Status}}
于 2013-03-05T07:38:35.633 回答