当将杀戮消息发送到任何其他过程必须死亡的过程时,有没有办法修改?

发布于 2025-02-11 14:03:28 字数 1732 浏览 2 评论 0原文

感谢您看看我的问题。

我从O'Reilly Francesco Cesarini和Simpson Thompson撰写了一个问题环问题的代码,练习4-2:过程戒指。

现在,这是我的问题,我如何修改代码,以便在将消息杀死发送到任何过程时,所有其他过程都应自动死亡,而不会通过戒指传播消息。

即使您无法解决它,也要至少感谢它。这是为了我自己对如果发生的方式会发生什么,我将再次感谢您分享代码和原始问题,以便你们能理解。

原始问题:编写一个程序,该程序将创建在环中连接的N过程,如图4-17所示。一旦开始,这些过程将在Thering周围发送M数量消息,然后在收到退出消息时优雅地终止。你可以开始 带有呼叫戒指的戒指:开始(M,N,消息)。

代码

-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.

如果有任何拼写错误,请原谅我,我真的很感激。太感谢了。

Thanks for taking a look at my question.

I wrote a code for the question ring problem from the o'reilly francesco cesarini and simpson thompson, Exercise 4-2: The Process Ring.

Now here's my question,How can I modify the code so that when message kill is sent to any process, all the other process should die automatically without the message getting propagated through the ring.

Even If you can't solve it, just thanks for at least looking at it. This is for my own curiosity on what would happen if this is how it goes and thanks again I'll share the code and the original question so that you guys can understand.

Original question : Write a program that will create N processes connected in a ring, as shown in Figure 4-17. Once started, these processes will send M number of messages around thering and then terminate gracefully when they receive a quit message. You can start the
ring with the call ring:start(M, N, Message).

This is the reference

The Code :

-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.

Pardon me If there's any spelling mistake and I would really appreciate it. Thank you so much.

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

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

发布评论

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

评论(1

摘星┃星的人 2025-02-18 14:03:28

正如@brujobenavides在评论中所建议的那样,您可以链接 。如果其中一个链接过程终止,则ERLANG VM将自动终止所有其他链接过程。参见参考手册“从“学习一些erlang for for for Great Good” 以获取更多详细信息。

在您的示例中,更改spawner/2使用spawn_link/3而不是spawn/3

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

此方式loop/loop/1不需要再传播{停止,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;

请注意,在您的示例中,中央进程产卵其他过程也是戒指的一部分。这意味着a)每当另一个环中的一个过程中的一个和b)当中央进程死亡时,它也将被终止。

您可以通过不链接self()来避免这种情况:

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

As was suggested by @BrujoBenavides in a comment, you can link all processes in the ring. If one of the linked processes terminates, Erlang VM will automatically terminate all other linked processes. See the reference manual and a chapter from "Learn You Some Erlang for great good" for more details.

In your example change spawner/2 to use spawn_link/3 instead of spawn/3:

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

This way loop/1 does not need to propagate { stop, Pid } anymore:

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;

Note that in your example the Central Process spawning other processes is also part of the ring. This means that a) it will also be terminated whenever one of the other ring processes dies and b) the whole process ring will be terminated when the Central Process dies.

You can avoid this by not linking self():

spawner(N, Nring) ->
    if Nring == self() ->
        Pid = spawn(r, processes, [Nring]);
    true ->
        Pid = spawn_link(r, processes, [Nring])
    end,
    spawner(N - 1, Pid).
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文