【发布时间】:2015-01-13 19:24:24
【问题描述】:
所以我们的想法是,我们需要接收多个子进程来生成/监控,但我们需要启动监控进程,使它们一次只能处理少于 10 个子进程。因此,如果我们接收 35 个子进程,我们需要 4 个监视器,3 个监视 10 个子进程,一个监视 5 个。
问题是我很难弄清楚为什么我为此目的编写的代码会失败。代码如下:
-module(watcher).
-import(sensor, [start/0]).
-export([start/1, stop/0]).
start(NrSlaves) ->
MasterPids = [],
MasterPid = spawn(fun() -> master_starter(NrSlaves, MasterPids) end),
register(master, MasterPid),
ok.
stop() ->
master ! die,
ok.
slave_pid_to_nr(SlavePid, SlavePids) ->
slave_pid_to_nr(SlavePid, SlavePids, 1).
slave_pid_to_nr(SlavePid, [SlavePid | _Tail], SlaveNr) ->
SlaveNr;
slave_pid_to_nr(SlavePid, [_Head | Tail], SlaveNr) ->
slave_pid_to_nr(SlavePid, Tail, SlaveNr + 1).
slave_change_pid(OldSlavePid, NewSlavePid, SlavePids) ->
lists:map(
fun(Pid) ->
if
Pid == OldSlavePid ->
NewSlavePid;
true ->
Pid
end
end,
SlavePids
).
%This is the part that errors out
master_starter(NrSlaves, MasterPids) ->
if (NrSlaves/10) =< 1 ->
MasterPids = MasterPids ++ [spawn_link(fun() -> master_start(NrSlaves) end)];
true->
MasterPids = MasterPids ++ [spawn_link(fun() -> master_start(10) end) || lists:seq(1, (NrSlaves/10))],
master_starter(NrSlaves-10, MasterPids)
end,
receive
die ->
io:fwrite("Monitor: received die~n"),
lists:foreach(fun(MasterPid) -> MasterPid ! die end, MasterPids)
end.
master_start(NrSlaves) ->
process_flag(trap_exit, true),
io:fwrite("monitor: started~n", []),
SlavePids = [spawn_link(fun() -> slave_start(SlaveNr) end) || SlaveNr <- lists:seq(1, NrSlaves)],
master_loop(SlavePids).
master_loop(SlavePids) ->
receive
die ->
io:fwrite("Monitor: received die~n"),
lists:foreach(fun(SlavePid) -> SlavePid ! die end, SlavePids);
{SlaveNr, Measurement} ->
io:fwrite("Sensor# ~p measures ~p~n", [SlaveNr, Measurement]),
master_loop(SlavePids);
{'EXIT', SlavePid, _Reason} ->
SlaveNr = slave_pid_to_nr(SlavePid, SlavePids),
io:fwrite("Monitor: Sensor ~p with PID ~p died because of a crash~n", [SlaveNr, SlavePid]),
NewSlavePid = spawn_link(fun() -> slave_start(SlaveNr) end),
NewSlavePids = slave_change_pid(SlavePid, NewSlavePid, SlavePids),
master_loop(NewSlavePids)
end.
slave_start(SlaveNr) ->
% SlavePid = lists:nth(SlaveNr, SlavePids),
io:fwrite("sensor ~p with PID ~p: started~n", [SlaveNr, self()]),
%%slave_loop(SlaveNr).
sensor:start(SlaveNr).
我收到如下错误:“进程中的错误 退出值:{{badmatch,[]},[{watcher,master_starter,2,[{file,"watcher .erl"},{line,39}]}]}"
任何帮助将不胜感激。它非常接近完成,但我只需要了解为什么这不起作用。
【问题讨论】:
标签: concurrency erlang