2

考虑所有链接在树中的进程,可以是正式的监督树,也可以是一些临时结构。

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

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

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

4

1 回答 1

4

它在文档中得到了很好的解释(第 12.4、12.5、12.6、12.7 节)

有两种情况:

  1. 您的进程由于一些错误的逻辑而终止。

它会引发错误,因此它可能正在工作中,这可能很糟糕。如果你想防止这种情况,你可以尝试定义机制,它涉及两个过程。第一个开始事务,第二个执行实际工作,然后,第一个提交更改。如果第二个进程发生了不好的事情(由于错误而死),第一个进程根本不会提交更改。

  1. 您正试图从外部终止该进程。例如,当您的主管重新启动或链接的进程死亡时。

在这种情况下,你也可以在某事中间,但是 Erlang 给了你trap_exit标志。这意味着,该进程不会死亡,而是会收到一条您可以处理的消息。这反过来意味着,该terminate函数将在您到达该receive块后被调用。因此,该过程将完成一大块工作,当它准备好进行下一个工作时,它会调用terminate并在那之后死亡。

所以你可以通过使用绕过退出trap_exit。您还可以绕过trap_exit发送exit(Pid, kill),即使它陷阱退出也会终止进程。

没有办法绕过exit(Pid, kill),所以要小心使用它。

于 2014-12-10T16:30:50.540 回答