Erlang进程终止:何时/何时发生?

时间:2014-12-10 15:42:58

标签: erlang shutdown otp supervisor

考虑所有在树中链接的流程,可以是正式的监督树,也可以是某种特殊的结构。

现在,考虑一下这棵树上的一些孩子或工人,上面有父母或上司。我有两个问题。

  1. 我们希望"优雅地"如果它需要被杀死或关闭,则退出此过程,因为它可能是更新某些帐户余额的一半。假设我们已经正确编码了一些终止功能,并通过适当的管道将此过程连接到其他人。现在假设这个过程正在其主循环中工作。终止的信号进入。确切地(或者可能是问题应该是什么时候)这种终止发生在哪里?换句话说,什么时候会终止被叫?这个东西会在它正在运行的循环中间正好抢先自己并且调用终止吗?它会等到循环结束但是再次开始循环之前吗?它只会在接收模式下执行吗?等

  2. 同样的问题,但没有已编码的终止功能。假设父进程是主管,并且此子进程遵循正常的OTP约定。父告诉孩子关机,或父母崩溃或其他什么。孩子处于主循环中。何时/何地/如何关闭?在主循环的中间?之后呢?等

1 个答案:

答案 0 :(得分:4)

很好地解释了in the docs (sections 12.4, 12.5, 12.6, 12.7)

有两种情况:

  1. 由于一些错误的逻辑,您的流程终止。
  2. 它会抛出一个错误,因此它可能处于工作中,这可能很糟糕。如果要防止这种情况,可以尝试定义涉及两个进程的机制。第一个开始事务,第二个开始实际工作,之后,第一个提交更改。如果第二个进程发生了不好的事情(它因为错误而死亡),第一个进程就不会提交更改。

    1. 你正试图从外面杀死这个过程。例如,当您的主管重新启动或链接过程终止时。
    2. 在这种情况下,您也可以处于某种状态,但Erlang会为您提供trap_exit标志。这意味着,该过程将收到一条消息,而不是死亡,您可以处理。这反过来意味着,在到达terminate块之后将调用receive函数。所以这个过程将完成一大块工作,当它准备好接下来的时候,它会调用terminate并在之后死掉。

      因此,您可以使用trap_exit绕过退出。您也可以绕过trap_exit发送exit(Pid, kill),即使陷入了退出流程也会终止进程。

      无法绕过exit(Pid, kill),因此请小心使用它。