正确管理Erlang并发

时间:2015-05-02 06:46:00

标签: multithreading erlang

我正在使用以下过程汇总一些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左右完成,这意味着在这张图片中有一个毫无意义的超时。真正应该说的是“在所有线程终止后”。

这样做是否有惯用的方式?

1 个答案:

答案 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消息。