Я написал простую программу в Erlang. Его задача - вычислить значение заданного многочлена 2 * x^2 + 3 * x + 5. Оба 2 * x^2 и 3 * x вычисляются параллельно, и в самом конце эти обе части складываются вместе, 5 добавлен и, наконец, мы получаем результат. Существует одна функция, вычисляющая 2 * x^2, вторая - вычисление 3 * x и последняя, которая вычисляет конечный результат. Вот код:Erlang - последовательные операторы получения с альтернативным сценарием
-module(count2).
-compile([export_all]).
%-export([f_main/0]).
%computes the value of the polynomial 2*x^2 + 3*x + 5
f_result() ->
{Arg1, Res_1} = receive
{f1, X1, Temp1} -> {X1, Temp1}
end,
Res_2 = receive
{f2, _, Temp2} -> Temp2
end,
Res = Res_1 + Res_2 + 5, %adds 5 to the result of 2*X^2+3*X
io:format("f(~p) = ~p~n",[Arg1, Res]),
f_result().
%when the line 14 was io:format("f(~p) = ~p~p,[X1, Res], the compilation error occured:
%variable 'X1' unsafe in 'receive'
f_2(PidWyn) -> %computes 2*X^2
receive
{f2, X} ->
Res = 2*math:pow(X,2),
PidWyn ! {f2, X, Res},
f_2(PidWyn);
{finish} ->
io:format("f_2 : finish~n")
end.
f_1(PidWyn) -> %computes 3*X
receive
{f1, X} ->
Res = 3*X,
PidWyn ! {f1, X, Res},
f_1(PidWyn);
{finish} ->
io:format("f_1 : finish~n")
end.
f_main() ->
PidW = spawn(?MODULE, f_result, []), %the process ID of the function that computes and displays the final result
Pid1 = spawn(?MODULE, f_1, [PidW]),
Pid2 = spawn(?MODULE, f_2, [PidW]),
L = [1,2,3,4,5],
[Pid1 ! {f1, X} || X <- L], %sends a series of messages to the function f_1
[Pid2 ! {f2, X} || X <- L], %sends a series of messages to the function f_2
Pid2 ! {finish},
Pid1 ! {finish},
PidW ! {finish}, %sends the message to the function f_result to make it stop
io:format("f_main : finish~n").
Как вы можете видеть, функция f_result
имеет два receive
заявления один за другим. Первый получает кортеж от f_1
, а второй получает кортеж от f_2
. После этого функция отображает результаты и вызывает сам вызов цикла.
Я хотел бы сделать f_result
функция получить {finish}
кортеж что бы сказать ему, чтобы перестать работать (аналогичное решение видна в f_1
и f_2
функции), но я не могу в месте, требуется receive
должным образом. Я пытался поставить
{Arg1, Res_1} = receive
{f1, X1, Temp1} -> {X1, Temp1};
{finish} -> io:format("f_result : finish~n"),
exit(0)
end,
, но он делает следующий вывод:
f_main : finish
f_result : finish
f_1 : finish
f_2 : finish
ok
я буду признателен, если вы можете дать мне несколько советов.
Большое спасибо за ваш изнурительный ответ. Собственно, после того, как я задал свой вопрос, я понял, что отправка атома 'finish' должна быть сопоставлена с другими сообщениями, но ваш ответ позволил мне лучше понять этот вопрос. Я знаю, что этот пример довольно примитивен, но это просто академические упражнения, чтобы изучить основы Эрланг. – user3855877