Как заставить процессы запускаться параллельно в Erlang? - PullRequest
4 голосов
/ 21 апреля 2010

startTrains () -> TotalDist = 100, Поезда = [trainA, trainB], PID = spawn (fun () -> поезд (1, длина (Поезда)) конец), [PID! {self (), TrainData, TotalDist} || TrainData <- Поезда], Получать {_From, Mesg} -> error_logger: info_msg ("~ n Mesg ~ p ~ n", [Mesg]) после 10500 -> обновление конец.

Итак, я создал два процесса с именем 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

Как заставить процессы работать параллельно / одновременно? Надеюсь, вы получите мои вопросы. Пожалуйста, помогите мне.

1 Ответ

6 голосов
/ 21 апреля 2010

Вы запускаете только один процесс, инициализированный функцией 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. Но на вашем текущем этапе продолжайте играть с примитивами эрланга, чтобы вначале почувствовать себя лучше.

...