談談erlang:exit/2

轉載請註明,來自:http://blog.csdn.net/skyman_2001

有同學用erlang:exit(Pid, normal)來關閉Pid進程,其實這樣Pid進程是不會自動退出的。官方文檔上對erlang:exit/2的說明講得很清楚:

Sends an exit signal with exit reason Reason to the processPid.

The following behavior apply if Reason is any term exceptnormal or kill:

If Pid is not trapping exits, Pid itself will exit with exit reasonReason. If Pid is trapping exits, the exit signal is transformed into a message{'EXIT', From, Reason} and delivered to the message queue ofPid. From is the pid of the process which sent the exit signal. See alsoprocess_flag/2.

If Reason is the atom normal,Pid will not exit. If it is trapping exits, the exit signal is transformed into a message{'EXIT', From, normal} and delivered to its message queue.

If Reason is the atom kill, that is ifexit(Pid, kill) is called, an untrappable exit signal is sent toPid which will unconditionally exit with exit reason killed.


簡而言之,如果Reason是kill,那麼是不能被捕獲的,會無條件退出;
如果Reason是normal,則進程是不會退出的,如果該進程設置了捕獲退出消息,則會收到{'EXIT', From, normal}消息;
如果Reason是原子值,則如果進程設置爲不捕獲退出消息,則該進程會退出;但如果設置了捕獲退出消息,則不會退出,而是收到{'EXIT', From, Reason}消息。

進程要設置爲捕獲退出消息,在進程初始化時調用:process_flag(trap_exit, true)。
這個知識點容易混淆,我們要理解清楚透徹,避免用錯。

還有就是如果是gen_server進程,最好不要直接用exit(),推薦這樣:
stop(Pid) when is_pid(Pid) ->
    gen_server:cast(Pid, stop).


handle_cast(stop, State) ->
    {stop, normal, State};

返回{stop, normal, State},該gen_server進程會調用terminate()回調然後終止。

注意:通過eixt(Pid,shutdown)或exit(Pid,kill)來終止gen_server進程,該gen_server進程是不會調用terminate()回調的!因爲沒捕捉退出消息。

發佈了184 篇原創文章 · 獲贊 13 · 訪問量 71萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章