Hi guys,
I tried something, but failed. The following code should spawn one process per list element but somehow if I give it a list of 4 elements, it will not stop creating processes and crash then. The part where the bug - I think - occurs is marked with %BUG.
simulation:simulate/2 starts everything, i.e. simulation:simulate([1,2,3,4],7), where 7 is the number of iterations. The element with the number 0 is created separately because it should never change it's value. The processes should get the PID of there previous and next neighbours so that they can exchange their values. I tried to debug it with the debuger im(). But it crashes. I saw that too many processes are created. Somehow, I don't find the mistake at the moment. Perhaps you notice something that's totally wrong?
-module(simulation).
-compile(export_all).
%-export().
f(Prev, Current, Next) ->
0.1 * Prev + 0.7 * Current + 0.2 * Next.
simulate([], _Iteration) -> [];
simulate([X], 0) -> [X];
simulate([X], Iteration) -> simulate([f(0.0, X, 0.0)], Iteration - 1);
simulate(Liste, 0) -> Liste;
simulate(Liste, Iteration) ->
PidStarter = self(),
{Number, ProcList} = startProcesses(Liste, Iteration, PidStarter), %BUG
Connector = spawn(fun() -> simProcessStarter(0.0, PidStarter, Iteration, 0) end), %untested
[H1, H2 | _] = ProcList,
H1 ! {startinformation, Connector, H2}, %untested
ReversedProcList = lists:reverse(ProcList),
[L1, L2 | _] = ReversedProcList,
L1 ! {startinformation, L2, Connector},%untested
fold(ProcList),%untested
evaluate(Number, []).%untested
fold([]) -> ready;
fold([_X1]) -> ready;
fold([_X1, _X2]) -> ready;
fold([X1, X2, X3 | Tail]) ->
X2 ! {statusinformation, X1, X3},
fold([X2, X3 | Tail]).
evaluate(0, List) ->
List;
evaluate(N, List) ->
receive
{N, Current} ->
Result = [Current | List]
end,
evaluate(N-1, Result).
% returns {number of processes, list of processes started}
startProcesses(Liste, Iteration, PidStarter) -> startProcesses(Liste, 0, Iteration, [], PidStarter).
startProcesses([], N, _Iteration, List, _PidStarter) -> {N, lists:reverse(List)};
startProcesses([H | T], N, Iteration, List, PidStarter) ->
startProcesses([T], N + 1, Iteration, [spawn(fun() -> simProcessStarter(H, PidStarter, Iteration, N + 1) end) | List], PidStarter).
simProcessStarter(Current, PidStarter, Iteration, Number) ->
receive
{startinformation, PidPrev, PidNext} ->
Result = simProcess(Current, PidPrev, self(), PidNext, Iteration, Number)
end,
PidStarter ! Result.
simProcess(Current, _PidPrev, _PidCurrent, _PidNext, 0, Number) ->
{Number, Current};
simProcess(Current, PidPrev, PidCurrent, PidNext, Iteration, Number) ->
PidNext ! {prev, PidCurrent, Current, Iteration},
receive
{prev, PidPrev, Prev, Iteration} -> Prev
end,
PidPrev ! {next, PidCurrent, Current, Iteration},
receive
{next, PidNext, Next, Iteration} -> Next
end,
New = f(Prev, Current, Next),
simProcess(New, PidPrev, PidCurrent, PidNext, Iteration-1, Number).