erlang熱更新會kill掉進程嗎?

我的個人博客網站雲諾說上線啦!所有文章都搬到新地址了,點擊圍觀吧!

問題:erlang熱更新會kill掉還在調用'old' 代碼的進程嗎?

前幾天在跟人討論erlang模塊熱更新時對方認爲不會kill掉還在調用‘old’代碼的進程,原因是這會破壞掉erlang的穩定性,這樣熱更也就完全沒有了意義!今天有時間我來寫這篇博客驗證下。

大家都知道erlang VM爲每個模塊最多保存2份代碼,當前版本'current'和舊版本'old',當模塊第一次被加載時,代碼就是'current'版本。如果有新的代碼被加載,'current'版本代碼就變成了'old'版本,新的代碼就成了'current'版本。erlang用兩個版本共存的方法來保證任何時候總有一個版本可用,對外服務就不會停止。

測試代碼如下:

 

-module(test).
-compile(export_all).

start() ->
    Pid = spawn(fun() -> do_loop() end),
    register(?MODULE, Pid).
    
do_loop() ->
    receive
        Msg ->
            io:format("~p~n", [Msg])
    end,
    do_loop().

hot_update(Mod) ->
	code:purge(Mod),
	code:load_file(Mod).

測試結果如下:

 

從結果可以看出erlang熱更時會kill掉一直使用‘old’代碼的進程,原因是如果進程一直在自己loop裏面,就會一直跑着‘old‘版本的代碼, 那麼如何解決這個問題呢? 請接着看下面

代碼修改如下:

 

-module(test).
-compile(export_all).

start() ->
    Pid = spawn(fun() -> do_loop() end),
    register(?MODULE, Pid).
    
do_loop() ->
    receive
        code_switch ->
            ?MODULE:do_loop();
        Msg ->
            io:format("~p~n", [Msg]),
            do_loop()
    end.
    

hot_update(Mod) ->
    code:purge(Mod),
    code:load_file(Mod).

測試結果如下:

 

在每次更新完之後給進程發送一條code_switch消息, 這樣就沒問題了,但是爲什麼呢? 這就涉及到erlang函數內部調用和外部調用的問題了,詳細請參考下面幾篇文章:

http://blog.csdn.net/mycwq/article/details/43372687

http://blog.csdn.net/mycwq/article/details/41175237

http://erlang.org/doc/reference_manual/code_loading.html#id86381

http://learnyousomeerlang.com/designing-a-concurrent-application#hot-code-loving

 

祝生活愉快!

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