Concurrency 我应该创建多个进程以获得乐趣,还是创建一个进程并发送多条消息?

Concurrency 我应该创建多个进程以获得乐趣,还是创建一个进程并发送多条消息?,concurrency,process,erlang,idioms,Concurrency,Process,Erlang,Idioms,假设我有一个文件名列表(.zip)。我希望并发(并行)提取文件,并对每个提取的文件并行处理。我当前的代码是: start() -> % .. Pid = spawn_link(fun process/0), Pid ! {self(), process_stats}, receive {Pid, Response} -> Response; {'EXIT', Pid, Reason} -> .. end.

假设我有一个文件名列表(.zip)。我希望并发(并行)提取文件,并对每个提取的文件并行处理。我当前的代码是:

start() ->
    % ..
    Pid = spawn_link(fun process/0),
    Pid ! {self(), process_stats},
    receive
        {Pid, Response} -> Response;
        {'EXIT', Pid, Reason} -> ..
    end.

process() ->
    receive
        {Pid, process_stats} ->
            Apps = get_apps(),
            Archive = spawn_link(fun archive/0),
            lists:foreach(fun({Id, AppId}) ->
                              Archive ! {self(), {extract, ?STATS_DIR++AppId++".zip", Pid}}
                          end, Apps),
            process();
        {Pid, {onextract, FilesList, Reply}} ->
            Reply ! {self(), ok},  %
            process();            
    end.

archive() ->
    receive
        {Pid, {extract, FilePath, Reply}} -> % Passing in Reply so that the receive block can send back message to the initiator. But it looks odd.
            {ok, FilesList} = zip:extract(FilePath, [{cwd, ?STATS_DIR}]),
            Pid ! {self(), {onextract, FilesList, Reply}},
            archive()
    end.

get_apps() -> ok. % returns a list of file names.
所以,我的问题是我只发送了一个进程
Archive
,并发送了多条消息。在这样做时,这些信息是否会被同时处理?ErlangVM内部的文章说每个调度器都有多个运行队列,所以我假设消息可以并发处理?或者,为了同时处理消息,我是否必须生成多个进程并分别向它们发送一条消息?喜欢

        lists:foreach(fun({Id, AppId}) ->
                          Archive = spawn_link(fun archive/0),
                          Archive ! {self(), {extract, ?STATS_DIR++AppId++".zip"}}, % Here I don't have to send the Reply Pid as the receive statement is within.
                          receive
                              {Archive, {onextract, FilesList}} -> ok. % Is it ok to have nested receive blocks within a process?
                          end
                      end, Apps),

让进程具有嵌套的接收块可以吗?这里哪种方法更合适?

Erlang调度器调度进程而不是消息。如果您希望同时发生某些事情,则需要多个进程

进程内部的流程是连续的,因此您的archive/0实现是接收一条消息,然后提取,然后回复,然后在递归返回后接收下一条消息

由于生成一个进程的成本很低,所以每个文件都有一个进程并没有什么错。无需发送消息即可开始处理,您可以在闭包中传递文件名。此处,例如,使用列表理解:

[ spawn_link(fun() -> {ok, Fs} = zip:extract(Path, Options), Pid ! {repl, Fs} end) ||
      Path <- List ],
 %% collect replies
[spawn_link(fun()->{ok,Fs}=zip:extract(路径,选项),Pid!{repl,Fs}end)||

PathErlang调度器调度进程而不是消息。如果希望同时发生某些事情,则需要多个进程

进程内部的流程是连续的,因此您的archive/0实现是接收一条消息,然后提取,然后回复,然后在递归返回后接收下一条消息

由于生成进程的成本很低,因此每个文件都有一个进程没有什么错。无需发送消息即可开始处理,您可以在闭包中传递文件名。例如,使用列表理解:

[ spawn_link(fun() -> {ok, Fs} = zip:extract(Path, Options), Pid ! {repl, Fs} end) ||
      Path <- List ],
 %% collect replies
[spawn_link(fun()->{ok,Fs}=zip:extract(路径,选项),Pid!{repl,Fs}end)||
路径