如何在 Erlang 中使进程并行运行?

发布于 2024-08-30 04:26:45 字数 856 浏览 3 评论 0原文

startTrains() ->
    TotalDist = 100,
    Trains = [trainA,trainB ],
    PID = spawn(fun() -> 
            train(1,length(Trains)) end),
    [ PID ! {self(),TrainData,TotalDist} || TrainData <- Trains],
    receive
    {_From, Mesg} ->
        error_logger:info_msg("~n Mesg ~p ~n",[Mesg])
            after 10500 ->
        refresh
    end.

所以,我创建了两个名为trainA、trainB的进程。我想将这些进程增加 5,直到达到 100。我做了不同的进程,使每个火车(进程)并行增加其位置。但我很惊讶地顺序得到输出,即进程 trainA 结束,然后进程 trainB 开始。但我想同时增加自己。 我想运行这样的进程,


trainA 10 trainB 0
trainA 15 trainB 5
....
trainA 100 trainB 100 

但我得到了


trainA 0
....
trainA 90
trainA 95
trainA 100
trainA ends

trainB 0
trainB 5
trainB 10
.....
trainB 100

如何使进程并行/同时运行?希望你能收到我的问题。请帮我。

startTrains() ->
    TotalDist = 100,
    Trains = [trainA,trainB ],
    PID = spawn(fun() -> 
            train(1,length(Trains)) end),
    [ PID ! {self(),TrainData,TotalDist} || TrainData <- Trains],
    receive
    {_From, Mesg} ->
        error_logger:info_msg("~n Mesg ~p ~n",[Mesg])
            after 10500 ->
        refresh
    end.

so, I created Two Processes named trainA, trainB. I want to increment these process by 5 till it gets 100. I made different processes to make each of the train (process) increments its position parallely. But I was surprised to get the output sequentially i.e process trainA ends then process trainB starts. But I want to increment themselves at simultaneously.
I want to run processes like this


trainA 10 trainB 0
trainA 15 trainB 5
....
trainA 100 trainB 100 

but I m getting


trainA 0
....
trainA 90
trainA 95
trainA 100
trainA ends

trainB 0
trainB 5
trainB 10
.....
trainB 100

How to make the processes run parallel/simultaneously? Hope you get my Q's. Please help me.

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

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

发布评论

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

评论(1

℡寂寞咖啡 2024-09-06 04:26:45

您仅生成一个由函数 train/2 初始化的进程。您提供的代码不完整,所以我只能猜测,但我认为您的代码是错误的,因为您只有一个火车流程。寻求灵感:

-module(trains).

-export([startTrains/0]).

startTrains() ->
  TotalDist = 100,
  Names = [trainA,trainB ],
  Self = self(),
  Trains = [spawn_link(fun() -> 
          train(Name, Self) end) || Name <- Names],
  [ Train ! {start, Self, 0, TotalDist} || Train <- Trains],
  ok = collectResults(Names).

collectResults([]) -> ok;
collectResults(Trains) ->
  receive
    {stop, Name, Pos, Length} ->
      io:format("~p stops at ~p (~p)~n", [Name, Pos, Length]),
      collectResults(Trains -- [Name]);
    Msg ->
      io:format("Supervisor received unexpected message ~p~n", [Msg]),
      collectResults(Trains)
  after 10500 -> timeout
  end.

train(Name, Sup) ->
  receive
    {start, Sup, Pos, Length} -> run_train(Name, Sup, Pos, Length);
    Msg ->
      io:format("~p received unexpected message ~p~n", [Name, Msg]),
      train(Name, Sup)
  end.

run_train(Name, Sup, Pos, Length)
  when Pos < Length ->
    receive after 500 ->
        NewPos = Pos + 5,
        io:format("~p ~p~n", [Name, Pos]),
        run_train(Name, Sup, NewPos, Length)
    end;
run_train(Name, Sup, Pos, Length) ->
  Sup ! {stop, Name, Pos, Length}.

但如果我认真思考的话,我应该考虑 gen_fsm 和 OTP 原则。但在当前阶段,请继续使用 erlang 原语,以便首先获得更好的感觉。

You spawn only one process initialized by function train/2. Your presented code is incomplete so I can only guess but I think your code is wrong because you have only one train process. For inspiration:

-module(trains).

-export([startTrains/0]).

startTrains() ->
  TotalDist = 100,
  Names = [trainA,trainB ],
  Self = self(),
  Trains = [spawn_link(fun() -> 
          train(Name, Self) end) || Name <- Names],
  [ Train ! {start, Self, 0, TotalDist} || Train <- Trains],
  ok = collectResults(Names).

collectResults([]) -> ok;
collectResults(Trains) ->
  receive
    {stop, Name, Pos, Length} ->
      io:format("~p stops at ~p (~p)~n", [Name, Pos, Length]),
      collectResults(Trains -- [Name]);
    Msg ->
      io:format("Supervisor received unexpected message ~p~n", [Msg]),
      collectResults(Trains)
  after 10500 -> timeout
  end.

train(Name, Sup) ->
  receive
    {start, Sup, Pos, Length} -> run_train(Name, Sup, Pos, Length);
    Msg ->
      io:format("~p received unexpected message ~p~n", [Name, Msg]),
      train(Name, Sup)
  end.

run_train(Name, Sup, Pos, Length)
  when Pos < Length ->
    receive after 500 ->
        NewPos = Pos + 5,
        io:format("~p ~p~n", [Name, Pos]),
        run_train(Name, Sup, NewPos, Length)
    end;
run_train(Name, Sup, Pos, Length) ->
  Sup ! {stop, Name, Pos, Length}.

But if I would think it seriously I should look to gen_fsm and OTP principles. But in your current stage keep play with erlang primitives to take better feeling first.

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