2014-10-10 51 views
0

我想在我的gen_server停止時執行一些代碼。我有我的gen_server陷阱退出(我添加到init回調process_flag(trap_exit, true))。這很有效,因爲terminate/2在進程退出前總是被調用。我知道,因爲我陷入退出鏈接進程崩潰不會崩潰我創建的gen_server。我可以解決這個問題,但我想知道是否有替代使用process_flag(trap_exit, true)來實現這一目標?Erlang替代trap_exit?

我只想要一個「在進程退出」回調之前。還有其他的東西像這樣退出嗎?

+0

你想鏈接的進程殺死'gen_server',但是你也想'terminate'(或類似的)在退出時被調用嗎? – 2014-10-10 18:26:12

+0

沒錯。這是我的理解,如果我陷入退出沒有其他進程可以導致我的gen_server崩潰,如果出現問題,它真的應該。 – Stratus3D 2014-10-10 18:54:43

+0

我很確定陷阱退出只是導致它運行終止,然後退出。它實際上是否阻止gen_server停止? – kjw0188 2014-10-10 21:10:29

回答

1

@帕斯卡爾的回答是完全正確的,但我想提出另一個問題。

有時候你想通過gen_server產生進程,但通常你可以把它們放在監督層次結構中,這樣更安全。您可以通過one_for_all重啓策略產生由同一個主管產生的這些進程和gen_server。如果其中一個進程死亡,它們都會重新啓動。其次,你必須指定關機策略的超時時間 - 這將確保終止功能將被調用。

+0

這是有道理的...所以在這種情況下,可以使用trap_exit,因爲gen_server不會鏈接到任何東西? – Stratus3D 2014-10-13 12:14:13

+0

在這種情況下,您可以忘記'trap_exit'。可以不使用它。當你可以使用主管時,通常最好不要使用它。 – tkowal 2014-10-13 13:24:04

3

Fron的DOC:

當trap_exit被設置爲到達至過程被 轉換爲{「退出」,從,原因}消息,其可被接收作爲 普通消息真,則退出信號。如果trap_exit設置爲false,則會在 接收到非正常退出信號並且退出信號爲 傳播到其鏈接進程時退出進程。應用程序進程應該通常不會陷阱退出。

這意味着如果其任何鏈接的進程異常死亡,那麼將trap_exit標誌設置爲true的進程將不會退出。它必須有一個接收塊和一個子句來捕獲{'EXIT', From, Reason}形式的任何消息。在此接收條款中,您可以在最終停止流程之前完成所需的任務。

在gen_server中,您將不得不編寫回調Module:handle_info({'EXIT', From, Reason}, State) -> Result