user1101674
user1101674

Reputation: 1421

How to accumulate results with SSA in Erlang?

This is a total functional newbie question.

I'm trying to learn some Erlang and have created a (hopefully concurrent) Monte Carlo Simulation where multiple processes are spawned, which report their local results to the parent process via message passing.

So in the parent process I have something like

parent(NumIterations, NumProcs) ->
    random:seed(),

    % spawn NumProcs processes
    lists:foreach(
        spawn(moduleName, workerFunction, [self(), NumIterations/NumProcs, 0, 0]),
        lists:seq(0, NumProcs - 1)),

    % accumulate results
    receive
        {N, M} -> ???; % how to accumulate this into global results?
        _      -> io:format("error")
    end.

Let's say I want to sum up all Ns and Ms received from the spawned processes.

I understand that accumulating values is usually done via recursion in functional programming, but how to do that within a receive statement..?

Upvotes: 1

Views: 454

Answers (1)

mbesso
mbesso

Reputation: 715

You will have to receive the results in a separate process that acts as the "target" for the calculations. Here is a complicated way of doing multiplications that shows the principle:

-module(example).

-export([multiply/2, loop/2]).

multiply(X, Y) ->
    Pid = spawn(example, loop, [0, Y]),
    lists:foreach(fun(_) -> spawn(fun() -> Pid ! X  end) end, lists:seq(1, Y)).

loop(Result, 0) -> io:format("Result: ~w~n", [Result]);
loop(Result, Count) ->
    receive
        X -> loop(Result + X, Count - 1)
    end.

The multiply-function multiplys X and Y by first starting a new process with the loop-function and then start Y processes whose only task it is to send X to the loop-process.

The loop-process will receive the X:s and add them up and call itself again with the new sum as it its state. This it will do Y times and then print the result. This is basically Erlang's server pattern.

Upvotes: 1

Related Questions