Asynchronous Erlang:退出/关闭同步还是异步?

Asynchronous Erlang:退出/关闭同步还是异步?,asynchronous,process,erlang,signals,synchronous,Asynchronous,Process,Erlang,Signals,Synchronous,您有一个要终止的进程树,因此您向主管发送一个退出(PID,shutdown)。您还需要做其他事情,但在关闭此流程树之前无法完成。例如,假设此进程树写入数据库。你想彻底关闭一切。你想关闭数据库,但是显然你需要先关闭进程树,否则树可以在写数据库的中间。 我的问题是,当我发送退出信号时,它是同步的还是异步的?如果它是同步的,我似乎不担心,但是如果它是异步的,我需要做一些事情,比如建立一个进程监视器,并在继续关闭数据库之前检查树是否关闭,对吗 谢谢。简短回答:OTP关机是同步的。exit/2是单个异步消

您有一个要终止的进程树,因此您向主管发送一个退出(PID,shutdown)。您还需要做其他事情,但在关闭此流程树之前无法完成。例如,假设此进程树写入数据库。你想彻底关闭一切。你想关闭数据库,但是显然你需要先关闭进程树,否则树可以在写数据库的中间。 我的问题是,当我发送退出信号时,它是同步的还是异步的?如果它是同步的,我似乎不担心,但是如果它是异步的,我需要做一些事情,比如建立一个进程监视器,并在继续关闭数据库之前检查树是否关闭,对吗


谢谢。

简短回答:OTP关机是同步的。exit/2是单个异步消息

长回答:Erlang中的所有消息都是异步的。关机消息也不例外。但是,除了发送消息之外,关机还有很多事情要做。在发送退出信号后,主管侦听
{'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上查看源代码,如下所示:


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

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

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。