Erlang进程在断开连接后死亡

时间:2011-08-15 01:04:02

标签: erlang distributed

我得到了以下设置:

  • 使用fqdn usa.local和gca.local
  • 的2台服务器
  • 每个erlang节点名为alice@usa.local和bob@gca.local

当我在alice@usa.local上启动Alice(alice:start/0)时,它会在gca.local上生成链接的Bob(bob:start/1)。这两个处理都是陷阱退出。

当Alice死于某事时,Bob会收到通知并继续运行。 当Bob死于某事时,Alice会收到通知并继续运行。

当我切断网络连接时,Alice会收到Bob已经死于noconnection的通知,并且处理bob在bob@gca.local上死亡。

我不希望这种情况发生。我希望鲍勃继续跑,虽然它失去了与爱丽丝的联系。

我的问题是:

  • 我有没有这样做,我最初从Alice节点产生Bob?
  • 如何让Bob在连接丢失中幸免于难?

以下是代码:

-module (alice).
-compile (export_all).

start () ->
    register (alice, spawn (fun init/0) ).

stop () ->
    whereis (alice) ! stop.

init () ->
    process_flag (trap_exit, true),
    Bob = spawn_link ('bob@gca.local', bob, start, [self () ] ),
    loop (Bob).

loop (Bob) ->
    receive
        stop -> ok;
        {'EXIT', Bob, Reason} ->
            io:format ("Bob died of ~p.~n", [Reason] ),
            loop (Bob);
        Msg ->
            io:format ("Alice received ~p.~n", [Msg] ),
            loop (Bob)
    end.

-module (bob).
-compile (export_all).

start (Alice) ->
    process_flag (trap_exit, true),
    register (bob, self () ),
    loop (Alice).

loop (Alice) ->
    receive
        stop -> ok;
        {'EXIT', Alice, Reason} ->
            io:format ("Alice died of ~p.~n", [Reason] ),
            loop (Alice);
        Msg ->
            io:format ("Bob received ~p.~n", [Msg] ),
            loop (Alice)
    after 5000 ->
        Alice ! "Hi, this Bob",
        loop (Alice)
    end.

2 个答案:

答案 0 :(得分:2)

问题是io:format/2调用bob.erl的第13行。在spawn_link('bob@gca.local',...中创建新流程后,它会继承alice流程的组长,这是alice@usa.local的本地流程,因此您将在{{1}上看到bob的所有输出}} 终奌站。 alice@usa.local断开时alice@usa.local处理bob第12行的EXIT消息,但第13行的bob.erl电话失败,因为组长已断开连接。

快速解决方法是将所有bob的io:format/2来电更改为io:format/2。在这种情况下,所有bob的输出都将显示在io:format(user, Format, Data)终端上。

然而,在实际项目中,你真的应该使用gen_server行为,因为它处理许多粗略的情况,特别是对于节点间通信(不要忘记查看代码)。此外,您确实需要在此使用monitor/2或/和monitor_node/2代替bob@gca.locallink

答案 1 :(得分:-1)

每当我在代码中看到trap_exit时,我都会假设某人重新发明了OTP的某些部分。这似乎就是这种情况。

查看distributed applications文档。这样做只需要配置就可以了。

我已经使用了它大约7年的成功(目前在原子盒和arm5盒之间)。