2009-04-11 14 views
11

我在Delphi 2009中編寫了一個服務器應用程序,它實現了幾種類型的身份驗證。每種身份驗證方法都存儲在單獨的dll中。第一次使用身份驗證方法時,會加載相應的dll。該DLL只在應用程序關閉時纔會被釋放。從單個應用程序中的多個線程調用dll函數是否安全?

在服務器線程(連接)之間沒有任何形式的同步訪問dll是否安全?

回答

17

簡短的回答:

是的,這通常是可以調用多個線程DLL函數,因爲每個線程都有它自己的堆棧和調用DLL函數或多或少與調用任何其它的你自己的代碼的功能。

龍答:

如果是實際上可能取決於使用共享可變狀態與否的DLL函數。

例如,如果你做這樣的事情:

DLL_SetUser(UserName, Password) 
if DLL_IsAuthenticated then 
begin 
... 
end; 

然後,它肯定是不安全必須從不同的線程使用。在這個例子中,你不能保證DLL_SetUser並沒有其他線程之間DLL_IsAuthenticated使得以DLL_SetUser不同的調用。

但如果DLL功能不依賴於某種預定的狀態,即所有必要的參數都可以在一次和所有其他的配置是所有線程一樣,你可以認爲它會工作。

if DLL_IsAuthenticated(UserName, Password) then 
begin 
... 
end; 

但要小心:這可能是可能是一個DLL函數看起來原子,但在內部使用的東西,這是沒有的。例如,如果DLL創建一個始終具有相同名稱的臨時文件,或者它訪問一次只能處理一個請求的數據庫,則它將視爲共享狀態。 (對不起,我想不出更好的例子)

摘要:

如果DLL廠商說,他們的DLL是線程安全的我會使用它們從多個線程沒有鎖定。如果他們不 - 或者即使供應商不知道 - 你應該安全地玩並使用鎖定。

至少要等到你遇到性能問題。在這種情況下,您可以嘗試創建多個包裝DLL調用的應用程序/進程,並將它們用作代理。

+1

另一個例子可能是內部數據結構,其中導出的函數添加和/或刪除元素 - 如(失敗的)驗證請求列表或經過驗證的用戶列表。 – mghie 2009-04-11 10:08:19

-1

如果您在談論Win32 DLLs,它們的目的是在多線程應用程序調用時安全。我不知道你的DLL是做什麼的,但是如果你的DLL使用像文件或端口這樣的可鎖定資源,那麼可能會在DLL內部實現的基礎上出現問題。

我不熟悉Delphi 2009身份驗證DLL的工作。也許你應該將這些信息添加到標題中(你正在專門討論Delphi 2009 DLL)

+0

的Win32 DLL的是可以在Win32中被加載任何DLL。也許你的意思是「Windows系統DLL」呢?此外,德爾福2009年沒有任何「身份驗證DLL」的東西。這些必須是某種第三方DLL。 – 2009-04-13 14:55:54

4

爲了使您的DLL成爲線程安全的,您需要保護一個進程中的多個線程可以訪問的所有共享數據結構同時 - 在爲DLL編寫代碼與爲可執行文件編寫代碼之間沒有區別。

對於多個進程,併發訪問沒有風險,因爲每個進程都有自己的DLL數據段,因此從不同進程中看到具有相同名稱的變量實際上是不同的。實際上,在不同進程中提供相同DLL的數據實際上要困難得多,因此基本上需要實現用於進程間數據交換的相同內容。

請注意,DLL是特別的,因爲您在進程或線程附着到DLL或從DLL分離時收到通知。有關說明,請參閱DllMain Callback Function的文檔,有關如何在Delphi編寫的DLL中使用該示例的示例,請參閱this article。因此,如果你的線程並不完全獨立(並且沒有共享數據被寫訪問),那麼你將需要一些具有同步訪問的共享數據結構。各種通知可幫助您正確設置DLL中的任何數據結構。

如果您的DLL允許完全獨立執行導出的函數,還可以查看threadvar線程特定的變量。請注意,對於他們初始化最終確定部分不可用,但也許線程通知可以幫助您在那裏。

0

下面是這個問題 - 如果你不能控制源代碼(或者說文檔說明它是這樣),那麼你不能假設這個DLL是線程安全的,因此它假設它們是最差的。

相關問題