Я что-то пробовал, но не получилось. Следующий код должен порождать один процесс на элемент списка, но каким-то образом, если я дам ему список из 4 элементов, он не остановит создание процессов и crash тогда Часть, где ошибка - я думаю - происходит, отмечена как% BUG.
Simulation: Simulate / 2 запускает все, то есть Simulation: Simulate ([1,2,3,4], 7), где 7 - количество итераций. Элемент с номером 0 создается отдельно, потому что он никогда не должен менять свое значение. Процессы должны получить PID этих предыдущих и следующих соседей, чтобы они могли обмениваться своими значениями. Я попытался отладить его с помощью отладчика im (). Но это вылетает. Я видел, что создано слишком много процессов. Почему-то я не нахожу ошибку в данный момент. Возможно, вы заметили что-то совершенно неправильное?
-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).