Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
繁殖和接收的erlang竞态条件_Erlang - Fatal编程技术网

繁殖和接收的erlang竞态条件

繁殖和接收的erlang竞态条件,erlang,Erlang,我正在学习erlang,在第13章中,第一个练习是编写一个函数my_spawn,它在生成的消息崩溃/退出时捕获退出消息 -module(my_spawn1). -compile(export_all). my_spawn(Mod,Func,Args) -> {M1, S1, Mi1} = os:timestamp(), Pid = spawn(Mod,Func,Args), lib_misc:on_exit(Pid, fun(Why) ->

我正在学习erlang,在第13章中,第一个练习是编写一个函数my_spawn,它在生成的消息崩溃/退出时捕获退出消息

-module(my_spawn1).
-compile(export_all).

my_spawn(Mod,Func,Args) ->
    {M1, S1, Mi1} = os:timestamp(),
    Pid = spawn(Mod,Func,Args),
    lib_misc:on_exit(Pid, fun(Why) ->
                  {M2,S2,Mi2} = os:timestamp(),
                  ElapsedTime = (M2 - M1) * 1000000 + (S2 - S1) * 1000 + (Mi2-Mi1),
                  io:format("~p died with:~p~n consume time:~p(ms)", [Pid,Why,ElapsedTime]),
              end),
    Pid.
我的困惑是,如果在spawn_监视器之后,
Mod:Func(Args)
已经完成,但是退出(…)上的
lib_misc:on_exit(…)还没有设置,那么退出消息就会丢失,真的吗

如果这是正确的,那么如何抓住这种情况呢

[用Pascal编辑]

我添加了lib_misc:on_exit/2的代码

on_exit(Pid, Fun) ->
    spawn(fun() -> 
          process_flag(trap_exit, true), %% <label id="code.onexit1"/>
          link(Pid),                     %% <label id="code.onexit2"/>
          receive
              {'EXIT', Pid, Why} ->      %% <label id="code.onexit3"/>
              Fun(Why)   %% <label id="code.onexit4"/>
          end
      end).
on_退出(Pid,Fun)->
繁殖(乐趣()->
进程标志(陷阱退出,真),%%
链路(Pid),%
接收
{'EXIT',Pid,为什么}->%%
乐趣(为什么)%%
结束
(完)。
否,消息(与所有消息一样)将排队。但是,如果接收消息的进程终止,则其邮箱将丢失


如果A确实
spawn_monitor
生成B,并且B立即死亡,则A保证接收到停机消息。但是,如果A也死亡,则A的消息队列中的所有内容都将丢失。

退出上的函数所做的第一件事是生成一个进程,该进程将进程标志trap\u exit设置为true,因此它将受到“保护”以防崩溃,并将接收以下类型的消息:
{'exit',Pid,Why}

在下一行,它试图将自己链接到Pid;可能有两种情况:

  • Pid不存在(错误的值,已经死了…),那么on_退出进程将收到消息
    {'exit',Pid,noproc}
    ,并调用F(noproc)
  • Pid存在,则on_退出进程将在接收时等待,直到进程Pid因某种原因消失。on_exit将接收
    {'exit',Pid,Reason}
    并调用F(Reason)
我不明白你为什么说spawn_monitor,它不用于你的案例。无论如何,如果在on_exit函数中用monitor(process,Pid)替换link(Pid),甚至不需要使用trap_exit,因为如果Pid失效,monitor函数不会崩溃。在所有情况下,它都返回消息
{'DOWN',MonitorReference,process,Pid,Reason}
。on_出口可以修改如下:

on_exit(Pid, Fun) ->
    spawn(fun() -> 
          MonitorReference = monitor(process,Pid),
          receive
              {'DOWN',MonitorReference,process,Pid,Why} -> Fun(Why)
          end
      end).

很好,如果监视器进程在接收之前退出,但在创建监视器之后退出,会发生什么?我使用的是监视器,而不是系统进程,该进程将陷阱的进程标志设置为真/你是对的,noproc或noconnection将是原因这是否意味着在创建进程时创建邮箱,即使你没有对其调用接收命令?是的,邮箱是使用进程创建的,它可以在到达任何接收语句之前存储传入的消息。