要在进程之间传递信息,您可以使用! 将消息发送到另一个进程的邮箱,并使用receive clause 从进程邮箱中提取消息。这是一个例子:
-module(a).
-compile(export_all).
%% Worker process:
say(From, 2, 0) ->
From ! {self(), [1,2]};
say(From, A, B) ->
say(From, A-1, B-1).
%% Main process:
loop(0) ->
ok;
loop(Times) ->
Pid = spawn(a, say, [self(), 4, 2]),
receive %%waits here for result before spawning another process--no concurrency
{Pid, Result} ->
io:fwrite( "L is ~w ~n", [Result] )
end,
loop(Times-1).
%% Test:
run() ->
loop(4).
在外壳中:
7> c(a).
a.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,a}
8> a:run().
L is [1,2]
L is [1,2]
L is [1,2]
L is [1,2]
ok
9>
或者,您可以生成所有进程,然后在结果进入时读取它们:
-module(a).
-compile(export_all).
%% Worker process:
say(From, 2, 0) ->
From ! [1,2];
say(From, A, B) ->
say(From, A-1, B-1).
%% Main process:
loop(N) ->
loop(N, N).
loop(0, Times) ->
display_results(Times);
loop(N, Times) ->
spawn(a, say, [self(), 4, 2]),
loop(N-1, Times).
display_results(0) ->
ok;
display_results(Times) ->
receive
Result ->
io:format("L is ~w~n", [Result])
end,
display_results(Times-1).
%% Test:
run() ->
loop(4).
为确保您只收到来自您所派生的进程的 receive 消息,您可以这样做:
-module(a).
-compile(export_all).
%% Worker process:
say(From, 2, 0) ->
From ! {self(), [1,2]};
say(From, A, B) ->
say(From, A-1, B-1).
%% Main process:
loop(Times) ->
loop(Times, _Pids=[]).
loop(0, Pids) ->
display_results(Pids);
loop(Times, Pids) ->
Pid = spawn(a, say, [self(), 4, 2]),
loop(Times-1, [Pid|Pids]).
display_results([]) ->
ok;
display_results([Pid|Pids]) ->
receive
{Pid, Result} ->
io:format("L is ~w~n", [Result])
end,
display_results(Pids).
%% Test:
run() ->
loop(4).
像这样使用receive 存在一些风险:如果工作进程在将消息发送到您的主进程之前崩溃,那么您的主进程将在等待消息到达时无限期地卡在接收中崩溃的进程。一种解决方案:在接收中使用超时。另一个:使用 spawn_monitor()。