我正在尝试在Erlang中创建多个进程。我要为地图中的每个键创建一个过程。
我尝试使用折叠操作。以下是相同的代码段:
CreateMultipleThreads = fun(Key,Value,ok) ->
Pid = spawn(calculator, init_method, [Key,Value,self()])
end,
maps:fold(CreateMultiplThreads,[],Map).
执行maps:fold(CreateMultiplThreads,[],Map)
时,程序终止并出现以下错误:
init terminating in do_boot.
答案 0 :(得分:2)
init terminating in do_boot
不是您的问题。这仅表示某些原因导致您的节点无法启动。 Erlang有打印很多错误消息的习惯。您的实际错误可能在此上方几行(甚至很多行)。先看看那里。
话虽如此,我直接在erl
shell中尝试了您的代码:
$ erl
1> CreateMultipleThreads =fun(Key,Value,ok)-> Pid = spawn(calculator, init_method, [Key,Value,self()]) end.
#Fun<erl_eval.18.128620087>
2> Map = #{k1 => v1, k2 => v2}.
#{k1 => v1,k2 => v2}
3> maps:fold(CreateMultipleThreads,[],Map).
** exception error: no function clause matching erl_eval:'-inside-an-interpreted-fun-'(k1,v1,[])
in function erl_eval:eval_fun/6 (erl_eval.erl, line 829)
in call from maps:fold_1/3 (maps.erl, line 257)
这试图告诉您的是,您传递给maps:fold
的函数与预期的形式-no function clause matching <mangled-name> (k1,v1,[])
不匹配。
它正在尝试传递(k1, v1, [])
,但是您的函数期望(Key, Value, ok)
。 []
与ok
不匹配。
[]
来自哪里?它来自您最初传递给maps:fold
的累加器值。在每次迭代中,先前的结果将作为新的累加器传递,因此您需要考虑如何保持所有匹配。
如果您确实不希望得到结果,只需传递ok
作为初始累加器值,匹配ok
,并确保返回 ok
:
CreateMultipleThreads = fun(Key, Value, ok) ->
Pid = spawn(calculator, init_method, [Key, Value, self()]),
ok
end.
maps:fold(CreateMultipleThreads, ok, Map).
或者您可以对累加器进行一些有用的操作,例如收集进程ID:
Map = #{k1 => v1, k2 => v2},
CreateMultipleThreads = fun(Key, Value, Acc)->
Pid = spawn(calculator, init_method, [Key, Value, self()])
[Pid | Acc]
end,
Pids = maps:fold(CreateMultipleThreads, [], Map),
Pids.
很显然,我无法实际测试这一点,因为calculator:init_method/3
对我而言并不存在,但希望您能明白。
答案 1 :(得分:0)
init terminating in do_boot
四处寻找类似的错误,看来该错误可能是由不正确的命令行参数引起的,或者您的文件名与erlang文件名冲突。因此,您需要发布程序的运行方式。
下面是一个可行的示例,您也许可以适应您的情况-包括如何运行它:
calculator.erl:
-module(calculator).
-compile(export_all).
init(X, Y, Pid) ->
io:format("init() in Process ~w got args ~w, ~w, ~w~n",
[self(), X, Y, Pid]).
my.erl:
-module(my).
-compile([export_all]).
go() ->
FoldFunc = fun(Key, Value, Acc) ->
Pid = spawn(calculator, init, [Key, Value, self()]),
[Pid|Acc] % Returns new value for Acc
end,
Map = #{a => 3, b => 7, c => 10},
_Pids = maps:fold(FoldFunc, [], Map). % [] is the initial value for Acc.
当您调用fold
函数时,例如lists:foldl()
,lists:foldr()
,maps:fold()
,您遍历集合中的每个值(例如列表或映射),并对每个值执行一些操作,然后累积这些操作的结果, fold函数返回累加结果。
在外壳中:
~/erlang_programs$ erl
Erlang/OTP 20 [erts-9.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V9.3 (abort with ^G)
1> c(my).
my.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,my}
2> c(calculator).
calculator.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,calculator}
3> Calculators = my:go().
init() in Process <0.80.0> got args a, 3, <0.64.0>
init() in Process <0.81.0> got args b, 7, <0.64.0>
init() in Process <0.82.0> got args c, 10, <0.64.0>
[<0.82.0>,<0.81.0>,<0.80.0>] %Return value of my:go()
4>
您可能想要累积生成的进程的pid的原因是,接收带有生成的进程的pid标记的消息。例如,如果要从每个计算器获取结果,则可以使用如下的receive子句:
Pid = % One of the calculator pids
receive
{Pid, Result} ->
%Do something with result
每个计算器执行此操作的地方:
Pid ! {self(), Result}
类似这样的东西:
calculator.erl:
-module(calculator).
-compile(export_all).
init(X, Y, Pid) ->
io:format("init() in Process ~w got args ~w, ~w, ~w~n",
[self(), X, Y, Pid]),
RandNum = rand:uniform(5), % time it takes to perform calc
timer:sleep(RandNum * 1000), % sleep 1-5 seconds
Pid ! {self(), RandNum}. % send back some result
my.erl:
-module(my).
-compile([export_all]).
go() ->
FoldFunc = fun(Key, Value, Acc) ->
Pid = spawn(calculator, init, [Key, Value, self()]),
[Pid|Acc]
end,
Map = #{a => 3, b => 7, c => 10},
Calculators = maps:fold(FoldFunc, [], Map),
lists:foreach(fun(Calculator) ->
receive
{Calculator, Result} ->
io:format("Result from ~w is: ~w~n", [Calculator, Result])
end
end,
Calculators
).
在外壳中:
7> c(calculator).
calculator.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,calculator}
8> c(my).
my.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,my}
9> my:go().
init() in Process <0.107.0> got args a, 3, <0.64.0>
init() in Process <0.108.0> got args b, 7, <0.64.0>
init() in Process <0.109.0> got args c, 10, <0.64.0>
Result from <0.109.0> is: 5
Result from <0.108.0> is: 4
Result from <0.107.0> is: 3
ok