6

My .Net program uses a fortran Dll to perform a maths function (Arpack, solves eigen modes). I believe the fortran contains static varibles and generally isn't thread safe. Also it's very complicated and would probably take a lot of hard work to make it thread safe. The Dll isn't very large (700K) so I just want to load it many times (say 4, or maybe 8) to allow the threads to work concurrently. Anyone have any idea how I can do this? I hear that LoadLibrary will always return the same handle when called multiple times. So, as it stands my only solution is to have multiple copies of my Dll on disk (Arpack1.dll, Arpack2.dll etc) and load them as required. Pretty horrible.

Any ideas?

Euan

Euan
  • 63
  • 1
  • 3

3 Answers3

2

Loading the DLL is not the way to create a thread. Your two options are to use AppDomains or outright separate processes.

The easy way to do it might be to simply use a master/slave arrangement, where the logic that uses the library is all done in the slave process. The master kicks off as many "slaves" as it wants or needs, and then collects the return values.

Write the code in the "slave" as if it is single threaded, because... it is.

Use System.Diagnostics.Process.Start from the master, to launch these things.


In general, copying the DLL and loading all the copies is not a failsafe approach; the DLLs themselves may access OS resources like mutexes or even lockfiles. These won't be aware that the copies are supposed to be "separate".

If your library is purely a compute library and you REALLY REALLY want to do the copy-and-load-the-copies approach, you can create hardlinks to avoid having to duplicate the actual DLL file. (fsutil hardlink create on Win7 or Vista)

Cheeso
  • 189,189
  • 101
  • 473
  • 713
  • Are you sure it's possible using AppDomains? I have just tried it, but it didn't seem to work. I basically used this example and modified it a bit to call a method in the library: http://msdn.microsoft.com/en-us/library/3c4f1xde(v=vs.110).aspx – Karsten Jan 09 '14 at 16:55
2

The workaround you found is actually a pretty decent one. There might be small odds that LoadLibraryEx() with the LOAD_LIBRARY_AS_IMAGE_RESOURCE option will work. That option allows you to load it multiple times. I seriously doubt it though, the DLL almost certainly relies on getting its runtime support code initialized through DllMain.

One thing I didn't hear you mention is the pain of having to use GetProcAddress(). Make sure you do or you'll still stomp global variables when you start threading. Each thread must use its own address.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
1

As you figuered out, you cannot load the library multiple times. I guess you have two possibilities:

In both solutions you need to consider a method of data exchange betwen the processes/app domains. Anyway, it won't be a simple task!

Community
  • 1
  • 1
Dominik Fretz
  • 1,368
  • 9
  • 15
  • Hi, thanks for the answer. It seems that both of these solutions are more complex than simply copying the Dll. Is that not the case? – Euan Nov 19 '10 at 13:01
  • 1
    Yes, that will be more complex The question here is, do you want to do it right or should it just work for now. Chances are that you get around with copying, but at one point it will bite you. – Dominik Fretz Nov 22 '10 at 09:53