【问题标题】:Erlang: exit/shutdown synchronous or asynchronous?Erlang:退出/关闭同步还是异步?
【发布时间】:2015-02-11 12:15:50
【问题描述】:

你有一个想要杀死的进程树,所以你向主管发送一个退出(PID,关闭)。您还需要做其他事情,但在此流程树关闭之前无法完成。例如,假设这个进程树写入数据库。你想干净地关闭一切。您想关闭数据库,但显然您需要先关闭进程树,否则树可能正在写入数据库。

我的问题是,当我发送退出信号时,是同步的还是异步的?如果是同步的,我好像不用担心,但如果是异步的,我需要做一些事情,比如建立一个进程监视器,检查树是否关闭,然后再进行数据库关闭,对吗?

谢谢。

【问题讨论】:

    标签: asynchronous process erlang signals synchronous


    【解决方案1】:

    如果您需要自己管理,请自行监控:

    sneak_attack(BankGuard) ->
        monitor(process, BankGuard),
        exit(BankGuard, kill),
        Cash = receive {'DOWN', _, process, BankGuard, _} -> rob_bank() end,
        send_to_bahamas(Cash).
    

    在此示例中,rob_bank() 和之后的任何内容都被阻止等待来自 BankGuard 的 'DOWN' 消息。

    另外,请注意,这是一个比仅仅关闭某些东西更笼统的概念。 Erlang 中的所有消息都是异步的,但与 UDP 不同的是,排序(两个进程之间)和传递(只要目标是活动的)是有保证的。所以同步消息只是简单地监视目标,发送一个标记的消息,并在收到返回消息时阻塞。

    【讨论】:

      【解决方案2】:

      简短回答:OTP 关闭是同步的。 exit/2 是一条异步消息。

      长答案:Erlang 中的所有消息都是异步的。关机消息也不例外。但是,关闭不仅仅是发送消息。主管在发送退出信号后监听{'DOWN', ...} 消息。只有在收到“DOWN”消息或超时后才会继续,因此实际上它是同步的。签出主管源代码。在第 894 行,定义了实际进行退出调用的函数:

      shutdown(Pid, Time) ->
      case monitor_child(Pid) of
      ok ->
          exit(Pid, shutdown), %% Try to shutdown gracefully
          receive 
          {'DOWN', _MRef, process, Pid, shutdown} ->
              ok;
          {'DOWN', _MRef, process, Pid, OtherReason} ->
              {error, OtherReason}
          after Time ->
              exit(Pid, kill),  %% Force termination.
              receive
              {'DOWN', _MRef, process, Pid, OtherReason} ->
                  {error, OtherReason}
              end
          end;
      {error, Reason} ->      
          {error, Reason}
      end.
      

      源代码可以在这里查看GitHub:https://github.com/erlang/otp/blob/maint/lib/stdlib/src/supervisor.erl#L894

      另一方面,erlang:exit/2 调用只是一个异步退出信号

      【讨论】:

      • 但是如果我试图通过发送异步退出信号来关闭主管怎么办?这就是它应该如何完成的,对吧?所以看来我必须把这件事当作异步处理,等到验证关闭后再继续,对吗?
      • 那么该主管应该由另一个主管监督,除非它是您监督树中的最高主管。如果它是树中的顶级主管,则应用程序行为应处理关闭。您不需要在其上调用 exit/2。
      猜你喜欢
      • 1970-01-01
      • 2017-06-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多