本文介绍了erlang竞赛条件的产卵和接收的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

   - 模(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 death with:〜p〜n消费时间:〜p(ms),[Pid,Why,ElapsedTime]),
end),
Pid。

我的困惑是,如果在spawn_monitor之后, Mod:Func(Args) 已经完成,但$ code> lib_misc:on_exit(...)没有设置,所以退出消息会丢失,真的吗?



如果这是正确的,那么如何捕捉这种情况?



[由Pascal编辑] / strong>



我添加了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/>
接收
{'EXIT',Pid,为什么} - > %%< label id =code.onexit3/>
Fun(为什么)%%< label id =code.onexit4/>
end
end)。


解决方案

函数on_exit的第一件事是产生一个将process_flag trap_exit设置为true的进程,因此它是受到保护的而不是崩溃,而是会收到以下类型的消息: {'EXIT',Pid,Why}



在下一行,它尝试将自身链接到Pid; 2例可能:




  • Pid不存在(错误的值,已经死了...),那么on_exit进程将会收到消息 {'EXIT',Pid,noproc} 并调用F(noproc)。

  • Pid存在,那么on_exit进程将等待收到,直到过程Pid死于一些原因。 on_exit将收到 {'EXIT',Pid,Reason} 并调用F(Reason)。



我不明白你为什么谈论spawn_monitor,在你的情况下不会使用它。无论如何,如果在on_exit函数中用monitor(process,Pid)代替链接(Pid),甚至不需要使用trap_exit,因为如果Pid死了,监视器功能不会崩溃。在所有情况下,它返回消息 {'DOWN',MonitorReference,process,Pid,Reason} 。 on_exit可以这样修改:

  on_exit(Pid,Fun) - > 
spawn(fun() - >
MonitorReference = monitor(process,Pid),
receive
{'DOWN',MonitorReference,process,Pid,Why} - >乐趣(为什么)
end
end)。


I am learning erlang with book , In chapter 13, the first exercise is writing a function my_spawn, which catch exit message when spawned message crash/exited.

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

my confuse was, if after spawn_monitor, the Mod:Func(Args) was finished, but the lib_misc:on_exit(...) haven't setup, so the exit message will be lost, really ?

If that's correct, so how to catch this situation ?

[edit by Pascal]

I add the code for 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).
解决方案

The first thing the function on_exit does is to spawn a process that set the process_flag trap_exit to true, thus it is "protected" from crashes, and will receive instead messages of the type: {'EXIT', Pid, Why}.

On the next line it tries to link itself to Pid; 2 cases are possible:

  • the Pid does not exists (wrong value, already dead...) then the on_exit process will receive the message {'EXIT', Pid, noproc} and will call F(noproc).
  • the Pid exists, then the on_exit process will wait on receive until the process Pid dies for some Reason. on_exit will receive {'EXIT', Pid, Reason} and call F(Reason).

I don't understand why you speak about spawn_monitor, it is not used in your case. Anyway, if you replace link(Pid) by monitor(process,Pid) in the on_exit function, you even don't need to use trap_exit since the monitor function don't crash if the Pid is dead. In all cases it returns the message {'DOWN',MonitorReference,process,Pid,Reason}. on_exit could be modified like this:

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

这篇关于erlang竞赛条件的产卵和接收的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-22 17:21