Concurrency 我应该创建多个进程以获得乐趣,还是创建一个进程并发送多条消息?
假设我有一个文件名列表(.zip)。我希望并发(并行)提取文件,并对每个提取的文件并行处理。我当前的代码是: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.
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)||
路径