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
祝生活愉快!