考虑所有在树中链接的流程,可以是正式的监督树,也可以是某种特殊的结构。
现在,考虑一下这棵树上的一些孩子或工人,上面有父母或上司。我有两个问题。
我们希望"优雅地"如果它需要被杀死或关闭,则退出此过程,因为它可能是更新某些帐户余额的一半。假设我们已经正确编码了一些终止功能,并通过适当的管道将此过程连接到其他人。现在假设这个过程正在其主循环中工作。终止的信号进入。确切地(或者可能是问题应该是什么时候)这种终止发生在哪里?换句话说,什么时候会终止被叫?这个东西会在它正在运行的循环中间正好抢先自己并且调用终止吗?它会等到循环结束但是再次开始循环之前吗?它只会在接收模式下执行吗?等
同样的问题,但没有已编码的终止功能。假设父进程是主管,并且此子进程遵循正常的OTP约定。父告诉孩子关机,或父母崩溃或其他什么。孩子处于主循环中。何时/何地/如何关闭?在主循环的中间?之后呢?等
答案 0 :(得分:4)
很好地解释了in the docs (sections 12.4, 12.5, 12.6, 12.7)。
有两种情况:
它会抛出一个错误,因此它可能处于工作中,这可能很糟糕。如果要防止这种情况,可以尝试定义涉及两个进程的机制。第一个开始事务,第二个开始实际工作,之后,第一个提交更改。如果第二个进程发生了不好的事情(它因为错误而死亡),第一个进程就不会提交更改。
在这种情况下,您也可以处于某种状态,但Erlang会为您提供trap_exit
标志。这意味着,该过程将收到一条消息,而不是死亡,您可以处理。这反过来意味着,在到达terminate
块之后将调用receive
函数。所以这个过程将完成一大块工作,当它准备好接下来的时候,它会调用terminate
并在之后死掉。
因此,您可以使用trap_exit
绕过退出。您也可以绕过trap_exit
发送exit(Pid, kill)
,即使陷入了退出流程也会终止进程。
无法绕过exit(Pid, kill)
,因此请小心使用它。