5

我的 .Net 程序使用 fortran Dll 来执行数学函数(Arpack,解决特征模式)。我相信 fortran 包含静态变量,通常不是线程安全的。而且它非常复杂,可能需要大量的努力才能使其线程安全。Dll 不是很大(700K),所以我只想加载它很多次(比如 4 次,或者可能 8 次)以允许线程同时工作。有人知道我该怎么做吗?我听说 LoadLibrary 在多次调用时总是返回相同的句柄。因此,就目前而言,我唯一的解决方案是在磁盘上保存我的 Dll 的多个副本(Arpack1.dll、Arpack2.dll 等)并根据需要加载它们。相当可怕。

有任何想法吗?

尤安

4

3 回答 3

2

加载 DLL 不是创建线程的方法。您的两个选择是使用 AppDomains 或完全独立的进程。

最简单的方法可能是简单地使用主/从安排,其中使用库的逻辑全部在从属进程中完成。主机根据需要启动尽可能多的“从机”,然后收集返回值。

将代码写在“从属”中,就好像它是单线程的,因为……它是。

使用 System.Diagnostics.Process.Start 从 master 启动这些东西。


一般来说,复制 DLL 并加载所有副本不是一种故障安全方法;DLL 本身可以访问操作系统资源,如互斥锁甚至锁文件。这些人不会意识到副本应该是“分开的”。

如果您的库纯粹是一个计算库,并且您真的很想执行复制并加载副本的方法,您可以创建硬链接以避免复制实际的 DLL 文件。(fsutil hardlink create在 Win7 或 Vista 上)

于 2010-11-19T12:46:33.037 回答
2

您找到的解决方法实际上是一个相当不错的解决方法。带有 LOAD_LIBRARY_AS_IMAGE_RESOURCE 选项的 LoadLibraryEx() 可能会起作用。该选项允许您多次加载它。不过我对此表示严重怀疑,DLL 几乎可以肯定依赖于通过 DllMain 初始化其运行时支持代码。

我没有听到你提到的一件事是不得不使用 GetProcAddress() 的痛苦。确保你这样做,否则当你开始线程时你仍然会踩到全局变量。每个线程必须使用自己的地址。

于 2010-11-19T14:04:27.723 回答
1

正如您所知道的,您不能多次加载该库。我猜你有两种可能:

在这两种解决方案中,您都需要考虑一种在进程/应用程序域之间交换数据的方法。无论如何,这不会是一个简单的任务!

于 2010-11-19T12:50:15.830 回答