我正在實作一個支持實時軟體升級(無需行程重啟)的 Linux 應用程式。為了支持此功能,我將應用程式分為兩部分
- 模塊代理 - 與外部行程互動的應用程式的前端
- 模塊實作 - 動態共享模塊,可以在程式更新期間使用新實作卸載和重新加載。
高級方法是將應用程式置于靜止狀態,將傳入訊息保存在訊息佇列中,并用模塊代理中的新實作替換舊的共享模塊(使用 dlopen)。
但是,在升級階段,我將有兩個類似共享物件的實體,舊模塊實作和新模塊實作同時動態加載到模塊代理中。這可能嗎?它會導致符號沖突嗎?安全達到這種狀態的最佳方法是什么?

uj5u.com熱心網友回復:
在 Glibc 系統(即 Linux)上,您可以通過dlmopen API將共享物件的副本加載到專用命名空間。之后,您可以通過dlsym.
uj5u.com熱心網友回復:
動態共享模塊,可以在程式更新期間使用新實作卸載和重新加載。
一般來說,這種方法充滿危險。特別是,呼叫dlclose可能不會在您期望的時候實際卸載庫。何時可以和不能卸載庫的規則很微妙,而且沒有很好的檔案記錄。
您應該嘗試dlopen()使用該庫,然后使用dlclose()它,并驗證它是否確實已卸載(通過檢查/proc/$pid/maps)。
KamilCuk 建議的“兩個程序”方法將更加可靠。
我考慮了兩種行程方法,但在兩個行程之間移動訊息可能會導致性能問題
- 一個可以 100% 運行但速度稍慢的應用程式通常會擊敗一個快 10% 但只能在 99% 的時間內運行的應用程式。
- 在決定使用可能不可靠的架構之前,您應該衡量性能。
- 有一些方法可以使用 IPC 幾乎和單行程一樣快(例如共享記憶體)。
yugr@ 建議使用dlmopen(),這可能有效。但它的檔案和測驗甚至更少,而且也是特定于 Linux 的。
在升級階段,我將有兩個類似共享物件的實體
這將是一個更大的問題,但目前還不清楚為什么你不能dlclose()在新版本之前 使用舊版本dlopen()。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/341866.html
