Erlang 进程在断开连接后终止

发布于 2024-11-29 16:48:43 字数 2273 浏览 0 评论 0 原文

我进行了以下设置:

当我启动 Alice (alice:start/0< /code>) [email protected] 它会在 gca.local 上生成链接的 Bob (bob:start/1)。两个处理都是捕获出口。

当爱丽丝死于某种疾病时,鲍勃会收到通知并继续奔跑。 当鲍勃死于某种疾病时,爱丽丝会收到通知并继续跑步。

当我切断网络连接时,Alice 收到通知 Bob 因 noconnection 死亡,并且进程 bob 在 [电子邮件受保护]

我不希望这种情况发生。我希望鲍勃继续运行,尽管它失去了与爱丽丝的连接。

我的问题是:

  • 这与我最初从 Alice 节点生成 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 ('[email protected]', 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.

I got the following setup:

When I start Alice (alice:start/0) on [email protected] it spawns linked Bob (bob:start/1) on gca.local. Both processing are trapping exits.

When Alice dies of something, Bob gets notified and keeps on running.
When Bob dies of something, Alice gets notified and keeps on running.

When I cut the network connection, Alice gets notified that Bob has died of noconnection and process bob dies on [email protected].

I do not want this to happen. I want Bob to keep on running although it looses connection to Alice.

My questions are:

  • Has this something to do that I initially spawn Bob from the Alice node?
  • How can I make Bob to survive a connection loss?

Here goes the code:

-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 ('[email protected]', 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

东北女汉子 2024-12-06 16:48:43

问题是 bob.erl 第 13 行的 io:format/2 调用。当在 spawn_link('[email protected] 中创建新进程时',... 它继承了 alice 进程的组长,该进程是本地进程[电子邮件受保护] 这样您就可以看到全部bob 的输出class="__cf_email__" data-cfemail="0465686d6761447177652a686b676568">[电子邮件受保护] 终端时。[email protected] 已断开连接 bob 处理 bob 第 12 行的 EXIT 消息。 erl 但第 13 行的 io:format/2 调用失败,因为组长被 快速修复

方法是将 bob 的所有 io:format/2 调用更改为 io:format(user, Format, Data)。在这种情况下,所有 bob 的输出都将显示在 [email protected] 终端。

然而,在实际项目中,您确实应该使用 gen_server 行为,因为它可以处理许多粗糙的情况,特别是对于节点间通信(不要忘记查看代码)。此外,您确实需要使用 monitor/2 或/和 < a href="http://www.erlang.org/doc/man/erlang.html#monitor_node-2" rel="nofollow">monitor_node/2 而不是 linktrap_exit 在这里。

The problem is io:format/2 call on line 13 of bob.erl. When new process is created in spawn_link('[email protected]',... it inherit the group leader of alice process which is a process local to [email protected] so you will see all output from bob on [email protected] terminal. When [email protected] is disconnected bob handles EXIT message on line 12 of bob.erl but io:format/2 call on line 13 is failed because group leader was disconnected.

The quick fix is to change all bob's io:format/2 calls to io:format(user, Format, Data). In this case all bob's output will be displayed on [email protected] terminal.

However in real projects you really should use gen_server behavior because it handles many rough cases, especially for inter-node communication (don't forget to look at the code). Moreover you really need to use monitor/2 or/and monitor_node/2 instead of link and trap_exit here.

顾铮苏瑾 2024-12-06 16:48:43

每当我在代码中看到 trap_exit 时,我就认为有人正在重新发明 OTP 的某些部分。这里的情况似乎就是这样。

查看分布式应用程序文档。这只需配置即可完成您想要的操作。

我已经使用它大约 7 年了,取得了相当大的成功(目前介于 Atom 盒和 Arm5 盒之间)。

Whenever I see a trap_exit in code, I assume someone's reinventing some part of OTP. That seems to be the case here.

Take a look the distributed applications documentation. This does what you want in just configuration.

I've used it with pretty good amounts of success for about 7 years now (currently between an atom box and an arm5 box).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文