2012-08-07 74 views
1

我正在使用.so作爲我的程序的一種插件,以允許應用用戶定義的邏輯。程序的多重實例將運行,每個實例都有自己特定的.so,它定義了該程序實例的用戶特定邏輯。該程序理想情況下可以無限期運行,但有時會出現一些邏輯需要更改的情況,所以我有一個明智的想法,即檢測何時修改了.so並上傳了新的.so。這樣就可以在不殺死/重啓程序的情況下更改特定的實現邏輯(這可能會導致數據丟失)。如何允許,並正確加載,修改.so文件?

我有loadPlugin函數工作,並且我使用inotify來檢測何時.so被更改並再次加載它。這沒有按計劃進行。我假定所有的內存都加載到內存中,從那時起,它完全獨立於物理文件,但顯然情況並非如此。如果我更改.so文件而不會發出警告,我的程序會崩潰並出現段錯誤。如果我使用.so,然後複製一個新版本,程序不會崩潰 - 我知道它知道在刪除插件時將插件的一個版本保留在內存中。但是,當我的loadPlugin方法嘗試加載新修改的.so時,它只是返回對舊的 .so方法的引用,而不是新方法。我認爲它默認使用已經加載到內存中的版本,因爲它假定它們是相同的,但我特別希望它加載新版本!由於只有一個應用程序會使用.so,所以我保證它不會在我用新的.so加載時調用.so的方法,覆蓋.so的定義是安全的如果我只知道如何做到這一點。

我想知道什麼是解決這些問題的最佳方法是?我的第一個想法是在加載之前將.so文件的一個版本複製到另一個位置,以便即使原始文件被修改,我的程序也不會崩潰,但這並沒有解決主要問題。如何告訴inotify忽略它在內存中存儲的任何緩存版本的.so文件並加載新版本的插件?我是否需要在兩個獨立文件(plugin1.so,plugin2.so)之間切換,以便在plugin1.so正在運行時可以修改plugin2.so並加載它,釋放plugin1.so以進行更改?這是否甚至會起作用,還是會在我讀取一次後終止兩個版本的「緩存」,並且在第三次更改時無法加載插件?

ps。我相信你猜對了,但我正在linux上使用C++(特別是redhat或centos)。我可以在最終的運行環境中定義我的操作系統,所以雖然可移植性總是很好,但如果唯一的方法不是可移植的,我不需要它。

+2

文字蝙蝠俠聖牆! – 2012-08-07 15:42:49

+0

@詹姆斯:好吧,這不是一個簡單的問題... – 2012-08-07 15:46:51

+0

呵呵。我在一個使用.so文件的大型應用程序上工作,這些文件可以在運行時重新構建和重新加載;沒有文件鎖或延遲加載問題。我們沒有使用inotify或rm或類似的東西;只需調用'make'後跟一個內部庫重載函數調用即可。 – Rook 2012-08-07 15:48:10

回答

1

正如丹妮指出的,問題出在我的dlclose調用中。我傳遞了錯誤的標題,並沒有正確關閉DL。不久之後,我確定我可以正確加載更新的方法。仍然存在修改程序文件的問題,但我知道如果需要的話我可以解決這個問題。

1

當你更新它時,你是否嘗試過爲插件設置不同的SONAME? SONAME是同一個庫的不同版本的區別,這幾乎就是你所要求的。

如果你看看到/ usr/lib或/ lib中你的機器上,並想知道誰定義了符號鏈接創建那裏,它的SONAMES個別庫;-)

man ldman gcc應該告訴你如何在鏈接時指定SONAME。

+0

您的權利,我沒有指定soname,這可能會解決這個問題。但是,我想盡量減少開發人員稍後嘗試更改插件的潛在錯誤;如果我忘記更改soname他們可能會。理想情況下,我想忽略soname並強制它只抓取當前版本在我的插件目錄中。 – dsollen 2012-08-07 15:58:46