Erlang和process_flag(trap_exit,true)

时间:2011-07-16 21:50:20

标签: erlang

在观看了Erlang上的Pragmatic Studio屏幕后,Supervisors上的最后一个视频提到,为了让主管获得有关其中一个孩子的通知以便它可以正确地重新启动它,孩子应该注册{{1} }。也许我只是误解了作者(很可能我误解了很多),但我认为主管们会自动知道他们的孩子何时死亡(可能是通过spawn_link或背景中类似的东西)。这真的有必要吗?什么时候应该在实际案例中使用process_flag(trap_exit,true),因为文档明确说明了以下内容:

http://www.erlang.org/doc/man/erlang.html#process_flag-2

  

process_flag(trap_exit,Boolean)

     
    

当trap_exit设置为true时,到达进程的退出信号将转换为{'EXIT',From,Reason}消息,这些消息可作为普通消息接收。如果trap_exit设置为false,则如果它接收到除正常之外的退出信号并且退出信号传播到其链接进程,则进程退出。申请流程通常不会陷入退出.`

  

3 个答案:

答案 0 :(得分:27)

主管使用链接和陷阱退出,以便他们可以跟踪他们的孩子并在必要时重新启动它们。子进程确实必须陷阱退出以便由他们的主管妥善管理,实际上他们应该只在他们特别需要知道他们链接的某个进程死亡且他们不想让自己崩溃。

如果被困或没有被困,OTP行为能够正确处理监督。

答案 1 :(得分:26)

你有3个习语:

1 /我不在乎我的孩子过程是否死亡:

spawn(...)

2 /如果我的子进程崩溃,我想崩溃:

spawn_link(...)

3 /如果我的子进程终止(通常与否),我想收到一条消息:

process_flag(trap_exit, true),
spawn_link(...)

请参阅此示例并尝试不同的值(与2或0相反以引发异常,并使用trap_exit):

-module(play).
-compile(export_all).

start() ->
    process_flag(trap_exit, true),
    spawn_link(?MODULE, inverse, [2]),
    loop().

loop() ->
    receive
        Msg -> io:format("~p~n", [Msg])
    end,
    loop().

inverse(N) -> 1/N.

答案 2 :(得分:17)

在Erlang中,进程可以链接。这些链接是双向的。每当进程终止时,它会向所有链接进程发送退出信号。每个进程都将启用或禁用 trapexit标志。如果禁用该标志(默认),则链接进程一旦获得退出信号就会崩溃。如果通过调用system_flag(trap_exit, true)启用了该标志,则该过程会将收到的退出信号转换为退出消息,并且不会崩溃。退出邮件将在其邮箱中排队,并视为正常邮件。

如果您正在使用OTP主管,他们会为您处理trap_exit标志和详细信息,因此您无需关心它。

如果你正在实施一个监督机制,这可能是关于屏幕播放的(没有看到它),你将不得不处理trap_exit的事情。