Erlang gen_serever和普通進程啓動方式的區別

並不是簡單的通過spawn在子進程啓動函數中啓動一個進程然後返回{ok, Pid}就可以讓子進程擁有出錯自動重啓的功能。實際上,需要使用proc_lib:spawn_link或者proc_lib:start_link啓動子進程,才能在子進程出錯退出時讓supervisor自動重啓它

proc_lib:start_link和proc_lib:spawn_link的不同之處在於,前者是同步創建子進程,後者是異步創建子進程,proc_lib:start_link調用後會阻塞,直到子進程初始化完畢,調用proc_lib:init_ack後才返回。而proc_lib:spawn_link一調用就會立即返回子進程ID。



Erlang實踐心得-01   

 by達達 轉載自http://1234n.com/?post/qou3eb   

 正文中紅色字體爲本人筆記。

之前用OTP的時候不求甚解只求能用,所以對OTP的特性和內部機制缺乏深入的瞭解。這幾天重構架構的代碼,針對性的進行了一些實驗,在這裏分享一些心得體會。

supervisor的子進程

一開始使用supervisor的時候,我用的是init/1返回子進程規格列表的方式,並且所有子進程只有兩種類型,一種是supervisor進程,一種是gen_server。

但這次代碼重構中,我遇到一個情況。如果我可以啓動普通的進程而不是gen_server,我就可以把一些我覺得沒必要做成gen_server的模塊代碼精簡掉。因爲一些模塊代碼完全沒用到任何gen_server的優勢,只是借gen_server來做爲supervisor的子進程啓動。於是我便開始實驗如何在supervisor中啓動普通的進程。

通過實驗,我發現我原先對supervisor的理解完全是沒有根據的猜測,果然實踐纔是檢驗真理的唯一標準。

首先,我原以爲supervisor的子進程規格中提供的Module、Function、Arguments就是子進程的入口,supervisor會通過它來自己啓動子進程。但實際上,子進程規格提供的是子進程的啓動函數入口,supervisor通過調用這個入口函數來啓動子進程,而這個函數通過返回{ok, Pid}來告訴supervisor子進程創建成功。

其次,並不是簡單的通過spawn在子進程啓動函數中啓動一個進程然後返回{ok, Pid}就可以讓子進程擁有出錯自動重啓的功能。實際上,需要使用proc_lib:spawn_link或者proc_lib:start_link啓動子進程,才能在子進程出錯退出時讓supervisor自動重啓它。

上面的第二點,我是通過閱讀gen_server的代碼才瞭解到的,因爲一開始我用來做實驗的代碼沒有用spawn(因爲第一點的錯誤理解),但這個問題很容易就發現了,接着我用了spawn看似正確啓動了子進程,但實際上這些子進程一旦出錯退出就不會再被啓動。我換gen_server實驗了一遍,確信用gen_server是可以重啓的。於是我便閱讀gen_server:start_link的代碼一探究竟,從源碼中可以看到gen_server模塊調用gen模塊來啓動進程,而gen模塊最終通過proc_lib:start_link來啓動進程。

proc_lib:start_link和proc_lib:spawn_link的不同之處在於,前者是同步創建子進程,後者是異步創建子進程,proc_lib:start_link調用後會阻塞,直到子進程初始化完畢,調用proc_lib:init_ack後才返回。而proc_lib:spawn_link一調用就會立即返回子進程ID。

調試信息和錯誤信息

之前一直傻傻的不懂得在erlang進程啓動時加上-boot start_sasl,搞得很怕在supervisor啓動子進程時出錯,因爲一旦出錯就只能看到很簡單的一行錯誤提示,完全看不到堆棧跟蹤信息。但實際上只要在啓動erlang時加上-boot start_sasl,就可以看到更多提示信息提示了。

項目中進程會輸出一些文字信息來幫助調試程序,通常就是在需要的地方寫上io:format,但是這些提示信息的輸出在實際生產環境下是不需要的,而且也會帶來對於的性能損耗。重構代碼時我定義了一組宏來代替io:format輸出文字信息,代碼如下:

-ifdef(debug).
    -define(LOG(Msg, List), io:format(Msg, List)).
-else.
    -define(LOG(Msg, List), ok).
-endif.

這樣只需在Emakefile裏面添加或刪除{d, debug},就可以編譯出針對性不同的代碼了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章