回覆列表
-
1 # 成都茂大叔
-
2 # 紅豆雲的紅小豆
粗略地看,要實現動態庫的熱升級,需要注意4個點(以Linux為例,其他系統類似):
so檔案不依賴ldd載入(也就是主程式的ELF不要跟so檔案動態連結,這一點可以透過修改連結的命令列實現),而是自己在啟動時主動呼叫dlopen/dlclose/g_module_open/g_module_close這類函式載入和解除安裝so檔案。主程式使用inotify等監聽so檔案的修改事件。so檔案匯出熱更新相關的2個操作,比如可以叫做save_and_stop,restore_and_resume。save_and_stop需要把執行時的狀態進行序列化,放在記憶體或者檔案固定位置,比如一個檔案中,然後停止操作(重點是不要再改狀態)。restore_and_resume從這個位置把狀態讀回來(反序列化),然後繼續執行它的功能。主程式發現so檔案改動以後,呼叫save_and_stop,然後unload動態庫,然後load新的動態庫,然後呼叫restore_and_resume。根據具體業務不同,這個最好是程式流程中的一個原子操作,比如flush或者suspend一些佇列,暫停處理使用者輸入(主迴圈暫停,相關worker執行緒暫停)。如果你的so庫是無狀態的就更容易了,可以省去序列化反序列化的過程。但是一定要做好事件的同步,主程式不要在解除安裝和載入的中間狀態執行依賴於動態庫的操作。
要實現熱更,在不修改作業系統的前提下,so的載入機制必須由主程式接管,so更新後,手動或自動觸發 鎖定-載入-解鎖 的過程。