2010-11-19 104 views
5

我的.Net程序使用fortran Dll執行數學函數(Arpack,解決特徵模式)。我相信Fortran包含靜態變量,並且通常不是線程安全的。此外它非常複雜,可能需要花費很多精力才能使其線程安全。 Dll不是很大(700K),所以我只是想多次加載它(比如說4或者8),以允許線程同時工作。任何人有任何想法我可以做到這一點?我聽說LoadLibrary多次調用時總會返回相同的句柄。所以,現在我唯一的解決方案是在磁盤上有多個我的Dll副本(Arpack1.dll,Arpack2.dll等)並根據需要加載它們。非常可怕。多次加載Dll以允許在多線程中.Net

任何想法?

Euan

+0

Fortran dll是託管代碼還是非託管代碼? – CodesInChaos 2010-11-19 12:46:52

+0

有沒有像託管Fortran這樣的東西?如果是這樣,我很樂意使用它。 – 2010-11-19 13:11:30

+0

你可以得到Fortran。淨,但最後我看起來有點昂貴。認爲這是F77或可怕的東西 – Euan 2010-11-19 13:31:20

回答

2

您發現的解決方法實際上是一個相當不錯的解決方案。 LoadLibraryEx()和LOAD_LIBRARY_AS_IMAGE_RESOURCE選項可能會有一些小的可能性。該選項允許您多次加載它。我認真地懷疑它,DLL幾乎肯定依賴於通過DllMain初始化它的運行時支持代碼。

我沒有聽到你提到的一件事是不得不使用GetProcAddress()的痛苦。確保你做了,否則當你開始線程時,你仍然會跺腳全局變量。每個線程都必須使用自己的地址。

+0

同意。它要比通過舊的Fortran代碼拖網更好。 – Euan 2010-11-19 14:06:23

2

加載DLL不是創建線程的方式。 您的兩個選擇是使用AppDomain或完全獨立的進程。

簡單的做法可能是簡單地使用主/從配置,其中使用庫的邏輯全部在從過程中完成。主人根據自己的需要開啓儘可能多的「奴隸」,然後收集返回值。

將代碼寫入「slave」,就好像它是單線程的,因爲......它是。

使用來自主站的System.Diagnostics.Process.Start啓動這些事情。


通常,複製DLL並加載所有副本不是故障安全方法; DLL本身可以訪問操作系統資源,如互斥鎖或鎖文件。他們不會意識到這些副本應該是「獨立的」。

如果您的庫純粹是一個計算庫,並且您確實想要執行copy-and-load-the-copies方法,則可以創建硬鏈接來避免必須複製實際的DLL文件。 (在Win7或Vista上爲fsutil hardlink create

+0

你確定它可能使用AppDomains?我剛剛嘗試過,但似乎沒有工作。我基本上使用這個例子,並修改它來調用庫中的一個方法:http://msdn.microsoft.com/en-us/library/3c4f1xde(v=vs.110).aspx – Karsten 2014-01-09 16:55:43

0

正如你想象的那樣,你無法多次加載庫。 我想你有兩種可能性:

在兩種方案進程/應用程序域之間。無論如何,這不是一個簡單的任務!

+0

嗨,感謝您的回答。看來這兩種解決方案都比簡單複製Dll更復雜。情況並非如此嗎? – Euan 2010-11-19 13:01:46

+0

是的,這會更復雜這裏的問題是,你想要做對還是應該現在就行。機會是你複製,但有一次它會咬你。 – 2010-11-22 09:53:35