繁体   English   中英

Erlang - Spawn MFA vs Spawn Fun

[英]Erlang - Spawn MFA vs Spawn Fun

我一直在努力使用编程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。

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).

这是非常不同的代码。 (参见最后两个块。最后一个是第一个版本,另一个是第二个版本。)

我运行你的代码时没有看到任何问题,除了测试应该是Pid! {makeError, “测试”}。 所以元组的第二个字段是一个列表,而不是一个原子。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM