简体   繁体   English

如何在Erlang中创建一个保持活动的过程

[英]how to create a keep-alive process in Erlang

I'm currently reading Programming Erlang ! 我目前正在阅读Programming Erlang , at the end of Chapter 13, we want to create a keep-alive process, the example likes: 在第13章的结尾,我们想创建一个保持活动的过程,示例如下:

on_exit(Pid, Fun) ->
    spawn(fun() ->
            Ref = monitor(process, Pid),
            receive
                {'DOWN', Ref, process, Pid, Info} ->
                    Fun(Info)
            end
    end).
keep_alive(Name, Fun) ->
    register(Name, Pid = spawn(Fun)),
    on_exit(Pid, fun(_Why) -> keep_alive(Name, Fun) end).

but when between register/2 and on_exit/2 the process maybe exit, so the monitor will failed, I changed the keep_alive/2 like this: 但是,当在register/2on_exit/2之间时,该过程可能会退出,因此监视器将失败,我将keep_alive/2更改为:

keep_alive(Name, Fun) ->
    {Pid, Ref} = spawn_monitor(Fun),
    register(Name, Pid),
    receive
        {'DOWN', Ref, process, Pid, _Info} ->
            keep_alive(Name, Fun)
end.

There also an bug, between spawn_monitor/2 and register/2 , the process maybe exit. spawn_monitor/2register/2之间还存在一个错误,该过程可能会退出。 How could this come to run successfully? 如何才能成功运行? Thanks. 谢谢。

I'm not sure that you have a problem that needs solving. 我不确定您是否有需要解决的问题。 Monitor/2 will succeed even if your process exits after register/2. 即使您的进程在register / 2之后退出,Monitor / 2也会成功执行。 Monitor/2 will send a 'DOWN' message whose Info component will be noproc. Monitor / 2将发送“ DOWN”消息,其Info组件将为noproc。 Per the documentation: 根据文档:

A 'DOWN' message will be sent to the monitoring process if Item dies, if Item does not exist , or if the connection is lost to the node which Item resides on. 如果Item死亡, Item不存在或与Item所在节点的连接丢失, 则会向监视进程发送“ DOWN”消息。 (see http://www.erlang.org/doc/man/erlang.html#monitor-2 ). (请参阅http://www.erlang.org/doc/man/erlang.html#monitor-2 )。

So, in your original code 因此,在您的原始代码中

  1. register assocates Name to the Pid 寄存器将名称关联到Pid
  2. Pid dies 死亡
  3. on_exit is called and monitor/2 is executed 调用on_exit并执行monitor / 2
  4. monitor immediately sends a 'DOWN' message which is received by the function spawned by on_exit 监视器立即发送一个“ DOWN”消息,该消息由on_exit产生的函数接收
  5. the Fun(Info) of the received statement is executed calling keep_alive/2 调用keep_alive / 2执行接收到的语句的Fun(Info)

I think all is good. 我认为一切都很好。

So why you did't want to use erlang supervisor behaviour? 那么,为什么不想使用erlang主管行为呢? it's provides useful functions for creating and restarting keep-alive processes. 它提供了用于创建和重新启动保持活动进程的有用功能。

See here the example: http://www.erlang.org/doc/design_principles/sup_princ.html 请参阅此处的示例: http : //www.erlang.org/doc/design_principles/sup_princ.html

In your second example, if process exits before registration register will fail with badarg . 在您的第二个示例中,如果进程在注册之前退出,则register将失败并显示badarg The easiest way to get around that would be surrounding register with try ... catch and handle error in catch. 解决该问题的最简单方法是使用try ... catch寄存器并处理catch中的错误。

You can even leave catch empty, because even if registration failed, the 'DOWN' message, will be sent. 您甚至可以将catch保留为空,因为即使注册失败,也会发送'DOWN'消息。

On the other hand, I wouldn't do that in production system. 另一方面,我不会在生产系统中这样做。 If your worker fails so fast, it is very likely, that the problem is in its initialisation code and I would like to know, that it failed to register and stopped the system. 如果您的工作人员发生故障的速度如此之快,很可能是问题出在初始化代码上,我想知道,它无法注册并停止了系统。 Otherwise, it could fail and be respawned in an endless loop. 否则,它可能会失败,并以无休止的循环重新生成。

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

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