我正在使用以下过程汇总一些Erlang代码:
- Spawn a number of threads
- Each thread scans an IP address
- Report back to the main thread the results
我有主线程运行:
cve_receive() ->
receive
Msg ->
io:fwrite("~s~n", [Msg]),
cve_receive()
after 5000 ->
ok
end.
它在功能上是正确的,并接收它的意思,但我不确定如何正确管理退出条件。它目前只是暂停,但实际情况是所有线程通常在100ms左右完成,这意味着在这张图片中有一个毫无意义的超时。真正应该说的是“在所有线程终止后”。
这样做是否有惯用的方式?
答案 0 :(得分:1)
最简单的解决方案是通过在cve_receive
中保留一个计数器来创建障碍,以便您可以跟踪已完成的工作进程数。
类似的东西:
%% First Spawn N work processes
...
%% Then receive N messages.
cve_receive(N).
...
cve_receive(N) ->
receive
Msg ->
io:fwrite("~s~n", [Msg]),
case N == 1 of
true -> all_done;
false -> cve_receive(N-1)
end;
after 5000 ->
{timeout, N}
end.
如果您需要在案例过程中执行一些清理过程没有在超时间隔内完成,您可以存储进程ID的列表而不是计数器。 收到邮件时删除pid,并且在超时时你可以例如杀死列表中剩余的所有进程。
编辑:如果工作进程崩溃,上面的简单解决方案仍然有效,因为最终会出现超时。但您可以使用monitor/2功能处理DOWN
功能中的cve_receive
消息。