Concurrency Erlang:尝试生成只监视10个子进程的监视器集

Concurrency Erlang:尝试生成只监视10个子进程的监视器集,concurrency,erlang,Concurrency,Erlang,因此,我们需要引入许多子进程来生成/监视,但我们需要加速监视进程,使它们一次只能处理少于10个子进程。因此,如果我们考虑35个子进程,我们需要有4个监视器,3个监视10个子进程,1个监视5个子进程 问题是,我正在努力找出我为此目的编写的代码失败的原因。代码如下: -module(watcher). -import(sensor, [start/0]). -export([start/1, stop/0]). start(NrSlaves) -> MasterPids = [],

因此,我们需要引入许多子进程来生成/监视,但我们需要加速监视进程,使它们一次只能处理少于10个子进程。因此,如果我们考虑35个子进程,我们需要有4个监视器,3个监视10个子进程,1个监视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).
-模块(观察者)。
-导入(传感器,[start/0])。
-导出([开始/1,停止/0])。
开始(NRS)->
MasterPids=[],
MasterPid=spawn(fun()->master_启动器(nrsaves,MasterPid)结束),
寄存器(主、主PID),
好啊
停止()->
主人!死亡
好啊
从pid到nr(从pid,从pid)->
从pid到nr(SlavePid,SlavePid,1)。
从pid到nr(SlavePid,[SlavePid | u Tail],SlaveNr)->
斯拉夫纳;
从pid到nr(从pid,从头部到尾部,从尾部)->
从pid到nr(从pid、尾部、从+1)。
从属更改pid(旧从属pid、新从属pid、从属pid)->
列表:地图(
乐趣(Pid)->
如果
Pid==OldSlavePid->
新闻界;
正确->
Pid
结束
完,,
奴隶
).
%这是出错的部分
主启动器(NRS从、主PID)->
如果(nR/10)=<1->
MasterPids=MasterPids++[spawn_链接(fun()->master_开始(nrsaves)结束)];
正确->
MasterPids=MasterPids++[spawn_link(fun()->master_start(10)end)|列表:seq(1,(nrsaves/10))],
主启动器(NRU-10,主PID)
完,,
接收
模具->
io:fwrite(“监视器:接收到的模具编号”),
列表:foreach(fun(MasterPid)->MasterPid!模具末端,MasterPid)
结束。
主机启动(NRU从机)->
进程_标志(陷阱_退出,真),
io:fwrite(“监视器:已启动~n”,[]),
SlavePids=[spawn_link(fun()->slaven开始(SlaveNr)结束)| SlaveNr
接收
模具->
io:fwrite(“监视器:接收到的模具编号”),
列表:foreach(乐趣(SlavePid)->SlavePid!模具结束,SlavePid);
{SlaveNr,Measurement}->
io:fwrite(“传感器#~p测量~p~n”,[SlaveNr,测量],
主回路(SlavePids);
{'EXIT',SlavePid,{u Reason}->
SlaveNr=从pid到nr(SlavePid,SlavePid),
io:fwrite(“监视器:带PID~p的传感器~p因崩溃而死亡,[SlaveNr,SlavePid]),
NewSlavePid=spawn_link(fun()->slaver_start(SlaveNr)end),
NewSlavePids=从机更改pid(SlavePid,NewSlavePid,SlavePids),
主回路(新Lavepids)
结束。
从站启动(从站)->
%SlavePid=列表:n(SlaveNr,SlavePid),
io:fwrite(“带PID的传感器~p:started~n”,[SlaveNr,self()]),
%%从回路(SlaveNr)。
传感器:启动(SlaveNr)。
我得到的错误如下:“进程中的错误,退出值:{{badmatch,[]},[{watcher,master_starter,2,[{file,watcher.erl},{line,39}]}”


任何帮助都将不胜感激。它即将完成,但我只需要理解为什么这不起作用。

变量在erlang中是不可变的。所以

MasterPids = MasterPids ++ [spawn_link(fun() -> master_start(NrSlaves) end)];

将失败,因为您尝试修改MasterPids

代码中有三个问题

变量是不可变的,
MasterPids=MasterPids++…
将失败,并出现
badmatch
错误。请尝试分配给新变量,如
NewPids
MasterPids2

列表理解中缺少生成器。您应该有