【问题标题】:Erlang alternative to trap_exit?Trap_exit 的 Erlang 替代方案?
【发布时间】:2014-12-05 23:51:03
【问题描述】:

我想在我的 gen_server 停止时执行一些代码。我有我的 gen_server 陷阱出口(我在 init 回调中添加了process_flag(trap_exit, true))。这很好用,因为总是在进程退出之前调用terminate/2。我知道,由于我正在捕获崩溃的退出链接进程,因此不会使我创建的 gen_server 崩溃。我可以解决这个问题,但我想知道是否有替代使用 process_flag(trap_exit, true) 来实现这一点?

我只想要一个“在进程退出之前”回调。还有其他类似的退出吗?

【问题讨论】:

  • 您希望链接进程杀死gen_server,但您还希望在退出时调用terminate(或类似的)?
  • 没错。我的理解是,如果我捕获退出,则没有其他进程会导致我的 gen_server 崩溃,如果出现问题,它确实应该崩溃。
  • 我很确定捕获退出只会导致它运行终止然后退出。它是否真的阻止了 gen_server 停止?

标签: process erlang exit erlang-supervisor gen-server


【解决方案1】:

@Pascal 的回答完全正确,但我想提出另一种方法。

有时您希望通过gen_server 生成进程,但通常可以将它们放在监督层次结构中,这样更安全。您可以使用one_for_all 重启策略让这些进程和gen_server 由同一个主管生成。如果其中一个进程死亡,它们都会重新启动。其次,您必须为 shutdown strategy 指定超时 - 这将确保调用终止函数。

【讨论】:

  • 这是有道理的......所以在这种情况下使用 trap_exit 是否可以,因为 gen_server 不会链接到任何东西?
  • 在这种情况下,您可以忘记trap_exit。不使用也没关系。当您可以使用主管时,通常最好不要使用它。
【解决方案2】:

前文档:

当 trap_exit 设置为 true 时,到达进程的退出信号是 转换为 {'EXIT', From, Reason} 消息,可以接收为 普通消息。如果 trap_exit 设置为 false,则进程退出 它收到一个非正常的退出信号,退出信号是 传播到其链接的进程。申请流程应 通常不会有陷阱出口。

这意味着如果它的任何链接进程异常死亡,则将 trap_exit 标志设置为 true 的进程将不会退出。它必须有一个带有子句的接收块来捕获{'EXIT', From, Reason} 形式的任何消息。在此接收子句中,您可以在最终停止进程之前执行所需的操作。

在 gen_server 中,您必须编写回调 Module:handle_info({'EXIT', From, Reason}, State) -> Result

【讨论】:

    猜你喜欢
    • 2011-10-06
    • 2011-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-13
    • 2015-03-03
    • 2015-09-25
    相关资源
    最近更新 更多