erlangprocessparallel-processing

How to make Processes Run Parallel in Erlang?


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.


Solution

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