我一直在努力使用编程Erlang,第2版(Joe Armstrong的书)。我试图解决第13章中的第一个问题。
作为解决问题的方法 - 我想出了这个 -
-module(errorhandle1).
-export([my_spawn/3,loop/1,test_func/0]).
my_spawn(Mod,Fun,Args) ->
%SpawnedPidRef = myspawn_helper(Mod,Fun,Args),
%spawn(?MODULE , loop , [myspawn_helper(Mod,Fun,Args)]).
spawn(fun() -> loop(myspawn_helper(Mod,Fun,Args)) end).
myspawn_helper(Mod,Fun,Args) ->
statistics(wall_clock),
spawn_monitor(Mod,Fun,Args).
loop({SpPid,SpRef}) ->
io:format("Created Pid is : ~p~n",[SpPid]),
receive
{makeError,Msg} ->
SpPid ! Msg,
loop({SpPid,SpRef});
{'DOWN',SpRef, process,SpPid,Why} ->
{_, Time1} = statistics(wall_clock),
io:format("Down"),
io:format("Process spawn time = ~p microsecond ~n",[Time1])
end.
test_func() ->
receive
X ->
list_to_atom(X)
end.
上面的代码工作并产生所需的输出(第一步是解决问题)。然后我评论了这一行,并提出了以下程序,它与上面的程序完全相同,但是,我使用spawn / 3函数而不是spawn / 1,我似乎没有得到所需的输出。
-module(errorhandle1).
-export([my_spawn/3,loop/1,test_func/0]).
my_spawn(Mod,Fun,Args) ->
%SpawnedPidRef = myspawn_helper(Mod,Fun,Args),
spawn(?MODULE , loop , [myspawn_helper(Mod,Fun,Args)]).
%spawn(fun() -> loop(myspawn_helper(Mod,Fun,Args)) end).
myspawn_helper(Mod,Fun,Args) ->
statistics(wall_clock),
spawn_monitor(Mod,Fun,Args).
loop({SpPid,SpRef}) ->
io:format("Created Pid is : ~p~n",[SpPid]),
receive
{makeError,Msg} ->
SpPid ! Msg,
loop({SpPid,SpRef});
{'DOWN',SpRef, process,SpPid,Why} ->
{_, Time1} = statistics(wall_clock),
io:format("Down"),
io:format("Process spawn time = ~p microsecond ~n",[Time1])
end.
test_func() ->
receive
X ->
list_to_atom(X)
end.
执行上述模块的步骤: C(errorhandle1)。 Pid = errorhandle1:my_spawn(errorhandle1,test_func,[])。 Pid! {makeError,测试}。
有些人可以帮助我理解spawn / 3和spawn / 1的用法吗?
谢谢, Sathish所在。
答案 0 :(得分:3)
spawn(fun() -> loop(myspawn_helper(Mod,Fun,Args)) end).
不等同于
spawn(?MODULE , loop , [myspawn_helper(Mod,Fun,Args)]).
在第二种情况下[myspawn_helper(Mod,Fun,Args)]
是函数spawn/3
的参数。在函数调用之前计算参数的值。这意味着调用myspawn_helper(Mod,Fun,Args)
是在调用原始新进程外的spawn/3
之前进行的。您可以将其视为此代码
SpawnedPidRef = myspawn_helper(Mod,Fun,Args),
spawn(?MODULE , loop , [SpawnedPidRef]).
与spawn/1
的等价物看起来像
SpawnedPidRef = myspawn_helper(Mod,Fun,Args),
spawn(fun() -> loop(SpawnedPidRef) end).
现在你可以看到差异。实际上只有loop(SpawnedPidRef)
在新进程中完成。但是在您的第一个版本中,您将在新流程中执行loop(myspawn_helper(Mod,Fun,Args))
。你可以看到它像
spawn(fun() ->
SpawnedPidRef = myspawn_helper(Mod,Fun,Args),
loop(SpawnedPidRef)
end).
这是非常不同的代码。 (参见最后两个方框。最后一个是第一个版本,另一个是第二个版本。)
答案 1 :(得分:0)
我运行代码时没有看到任何问题,但测试应该是Pid! {makeError,"测试"}。所以元组的第二个字段是一个列表,而不是一个原子。