2011-07-16 24 views
15

看務實工作室屏幕投射在二郎,對監事的最後一個視頻提到後,爲了讓主管得到一個通知,其子約,因此它可以正確地重新啓動它時,孩子應該註冊process_flag(trap_exit, true)。也許我只是誤解了作者(而且我誤解的可能性非常高),但我認爲主管自動地知道他們的孩子何時死亡(可能通過spawn_link或類似的背景)。這真的有必要嗎?當一個人應該用在真實世界的情況下process_flag(trap_exit,真),因爲文件明確規定了以下內容:Erlang和process_flag(trap_exit,真)

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

process_flag(trap_exit,布爾)

當trap_exit設置爲true時,到達進程的退出信號將轉換爲{'EXIT',From,Reason}消息,這些消息可以作爲普通消息接收。如果trap_exit設置爲false,則進程退出,如果它接收到非正常的退出信號並且退出信號傳播到其鏈接的進程。應用程序通常不應陷阱exits.``

+0

需要在OTP應用程序中設置trap_exit標誌確實是一種特殊情況。大多數OTP應用程序不需要明確設置trap_exit標誌,因爲管理程序旨在根據子規範正確處理它們。 –

回答

24

你有3個成語:

1 /我不在乎,如果我的孩子進程死掉了:

spawn(...) 

2/I想要崩潰,如果我的子進程崩潰:

spawn_link(...) 

3 /我想收到一條消息,如果我的c希爾德過程結束(正常或不):

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. 
+0

Re#1 - 我經常這麼想,但後來我意識到當我的系統關閉時我希望該過程退出。這就是臨時監督的孩子所需要的。 – Dustin

+0

我不認爲這實際上回答了這個問題... –

+0

我也這麼認爲。我認爲@rvirding給出了 –

27

監使用鏈接和陷阱出口,以便他們可以跟蹤他們的孩子,並在必要時重新啓動他們。兒童進程而不是必須陷阱出口由他們的主管妥善管理,事實上他們應該只在他們特別需要知道他們所連接的某個進程死亡並且他們不希望自己崩潰時纔會陷入困境。

的OTP行爲都能夠妥善處理好監督,如果他們被困或不困。

14

在Erlang中,進程可以將鏈接到在一起。這些鏈接是雙向的。每當一個進程死亡時,它會向所有鏈接進程發送一個退出信號。每個進程都會啓用或禁用trapexit標誌。如果標誌被禁用(默認),鏈接的進程一旦獲得退出信號就會崩潰。如果標誌已經被調用啓用system_flag(trap_exit, true),進程將接收到的退出信號轉換成退出消息,它會崩潰。退出消息將在其郵箱中排隊並作爲正常消息處理。

如果您使用的是OTP主管,他們會爲您處理trap_exit標誌和細節,因此您不必關心它。

如果你正在實施一個監督機制,這可能是屏幕播放的內容(沒有看到它),你將不得不照顧trap_exit的事情。

+0

驚人的答案。 –