erlang 是否有办法修改当kill消息发送到任何进程时,所有其他进程都必须终止?

js81xvg6  于 2022-12-08  发布在  Erlang
关注(0)|答案(1)|浏览(127)

感谢您查看我的问题。
我写了一个代码来解决问题环的问题,这个问题来自于奥莱利·弗朗西斯科·切萨里尼和辛普森·汤普森的练习4-2:进程环。
现在我的问题是,我如何修改代码,以便当消息kill被发送到任何进程时,所有其他进程都应该自动死亡,而消息不会通过环传播。
即使你不能解决它,只是感谢至少看它。这是我自己的好奇心会发生什么,如果这是怎么回事,再次感谢我会分享代码和原来的问题,让你们可以理解。

原始问题:编写一个程序,创建N个连接成环的进程,如图4-17所示。一旦启动,这些进程将发送M个消息,然后在收到退出消息时优雅地终止。你可以用调用ring:start(M,N,Message)启动环。

代码

-module(r).
-export([start/3,processes/1]).

start(M, N, Message) ->
  io:format("Central Process pid: ~w\n", [self()]),
  { ok, NextPid } = spawner(N),
  ok = sender(Message, M, NextPid),
  ok = sender(stop, 1, NextPid),
  ok.

spawner(N) ->
  spawner(N, self()).
      
spawner(1, Nring) ->
  { ok, Nring };
            
spawner(N, Nring) ->
  Pid = spawn(r, processes, [Nring]),
  spawner(N - 1, Pid).
  
processes(Nring) ->
  loop(Nring).

loop(Nring) ->
  receive
    { stop, From } ->
      io:format("~w received stop from ~w\n", [self(), From]),
      Nring ! { stop, self() },
      ok;
    { Msg, From } ->
      io:format("~w received ~w from ~w\n", [self(), Msg, From]),
      Nring ! { Msg, self() },
      loop(Nring)
  end.
  
sender(Msg, Times, NextPid) ->
  NextPid ! { Msg, self() },
  ok = receiver(Msg),
  case Times > 1 of
    true ->
      sender(Msg, Times - 1, NextPid);
    false ->
      ok
  end.
  
receiver(Msg) ->
  receive
      { Msg, From } ->
      io:format("~w received ~w from ~w\n", [self(), Msg, From]),
      ok
  end.

如果有拼写错误请原谅,我将非常感激。非常感谢。

mwkjh3gx

mwkjh3gx1#

正如@BrujoBenavides在一条评论中所建议的,你可以 link 环中的所有进程。如果其中一个链接的进程终止,Erlang VM将自动终止所有其他链接的进程。更多细节请参见参考手册和“为伟大的利益学习Erlang”中的一章。
在您的示例中,将spawner/2更改为使用spawn_link/3而不是spawn/3

spawner(N, Nring) ->
    Pid = spawn_link(r, processes, [Nring]),
    spawner(N - 1, Pid).

这样,loop/1就不再需要传播{ stop, Pid }

loop(Nring) ->
    receive
        { stop, From } ->
            io:format("~w received stop from ~w\n", [self(), From]),
            %% All linked processes will be terminated
            %% once we break out the loop/1
            ok;

注意,在你的例子中,Central Process产生的其他进程也是环的一部分。这意味着a)当其他环进程中的一个死亡时,它也将被终止; b)当Central Process死亡时,整个进程环将被终止。
您可以通过不链接self()来避免这种情况:

spawner(N, Nring) ->
    if Nring == self() ->
        Pid = spawn(r, processes, [Nring]);
    true ->
        Pid = spawn_link(r, processes, [Nring])
    end,
    spawner(N - 1, Pid).

相关问题