2016-03-07 48 views
0

因此,我有一個使用C++編寫的多線程應用程序,整個應用程序使用異步事件處理模型實現。線程所調用的函數是基於一個id(數組索引),它的函數指針存儲在索引的一個數組中(具有id的值),即,如果我將具有id 45的事件插入事件隊列,其中一個線程選擇事件並調用其索引存儲在索引45處的函數。現在,其中一些函數位於dll/shared對象內,可以隨時通過來自不同id的事件來卸載這些函數。發生這種情況時,將調用FreeLibrary(或等效)。這導致應用程序崩潰,我相信這是因爲線程仍然在dll中執行函數。所以我的問題是,有沒有什麼辦法可以安全地卸載dll,而不必擔心線程仍然在dll中執行代碼,或者有沒有辦法檢查多少個線程仍在執行dll內的代碼?在多線程應用程序中安全地卸載DLL /共享對象

+1

因此,假設您確認現在沒有呼叫處於活動狀態。沒有固定的方法可以做,但假設你神奇地開發了一種方法。您驗證,卸載DLL,毫秒後,其中一個線程調用不再存在的過程。你會如何阻止? –

+1

對DLL的句柄使用'shared_ptr'。在調用FreeLibrary之前重置shared_ptr(或者更好,FreeLibrary由shared_ptr deleter調用)。所有其他線程在使用任何DLL函數之前,都會在DLL句柄中保留一個'weak_ptr'並將其鎖定。如果鎖定失敗,則意味着DLL已被釋放。 – sbabbi

+0

@ n.m。感謝您指出我錯過描述我的問題的極具可能性的競爭條件。這並不是說我不知道​​它,而是我希望有一些簡單的方法來解決它,因爲在我看來,這是使用DLL的多線程應用程序中最常見的問題。我想那不是這種情況。 – Shehzan

回答

1

您可能有一個對象,它在構造函數中加載庫,將其卸載到析構函數中,併爲庫中的每個符號使用非靜態成員函數包裝。那麼該對象的生命週期將是庫的生命週期。

現在您的問題已減少到管理多線程程序中的對象。可能shared_ptr將適合您的需求。也許你已經有了另一個共享對象,所以你可以簡單地將庫包裝器作爲數據成員放入該對象中。

+0

這和@sbabbi的評論看起來非常相似。但是,雖然這可能會在一個非常好的面向對象的包裝器中解決問題,但它看起來並不能解決整個問題,但我仍然可能會遇到可能會破壞系統的競爭條件。如果我錯了,請讓我知道。 – Shehzan

+0

這個想法實際上並不是很針對對象。它依賴於RAII和通用C++對象生存期規則。當然,你總是可以犯錯誤並在你的程序中進行比賽。但另一方面,這是可以做到的。像'shared_ptr'這樣的工具可以幫助正確管理多線程程序中的共享對象,無論這些對象是什麼以及它們擁有哪種資源。 –

相關問題