Загрузите Dll несколько раз, чтобы разрешить многопоточность в .Net - PullRequest
5 голосов
/ 19 ноября 2010

Моя программа .Net использует Fortran Dll для выполнения математической функции (Arpack, решает собственные режимы).Я считаю, что Фортран содержит статические переменные и, как правило, не является потокобезопасным.Кроме того, это очень сложно и, вероятно, потребуется много тяжелой работы, чтобы сделать его потокобезопасным.Dll не очень большой (700 КБ), поэтому я просто хочу загрузить его много раз (скажем, 4 или 8), чтобы потоки могли работать одновременно.У кого-нибудь есть идеи, как я могу это сделать?Я слышал, что LoadLibrary всегда будет возвращать один и тот же дескриптор при вызове несколько раз.Таким образом, в настоящее время мое единственное решение состоит в том, чтобы иметь несколько копий моей Dll на диске (Arpack1.dll, Arpack2.dll и т. Д.) И загружать их по мере необходимости.Довольно ужасно.

Есть идеи?

Euan

Ответы [ 3 ]

2 голосов
/ 19 ноября 2010

Обходной путь, который вы нашли, на самом деле довольно приличный. Могут быть небольшие шансы, что LoadLibraryEx () с опцией LOAD_LIBRARY_AS_IMAGE_RESOURCE будет работать. Эта опция позволяет загружать его несколько раз. Я серьезно сомневаюсь в этом, хотя, DLL почти наверняка полагается на инициализацию своего кода поддержки во время выполнения через DllMain.

Одна вещь, о которой я не слышал, это то, что вам пришлось использовать GetProcAddress (). Убедитесь, что вы это сделаете, иначе вы все равно будете топать глобальные переменные, когда начнете создавать потоки. Каждый поток должен использовать свой собственный адрес.

2 голосов
/ 19 ноября 2010

Загрузка DLL не способ создать поток.Ваши два варианта - использовать домены приложений или отдельные процессы.

Самый простой способ сделать это может состоять в том, чтобы просто использовать схему master / slave, где вся логика, которая использует библиотеку, выполняется в процессе slave.Мастер запускает столько «рабов», сколько ему нужно или нужно, а затем собирает возвращаемые значения.

Напишите код в «ведомом», как если бы он был однопоточным, потому что ... это так.

Используйте System.Diagnostics.Process.Start от мастера для запуска этих вещей.


В общем случае копирование DLL и загрузка всех копий не является отказоустойчивым подходом;Сами библиотеки могут получать доступ к ресурсам ОС, таким как мьютексы или даже файлы блокировки.Они не будут знать, что копии должны быть «отдельными».

Если ваша библиотека является чисто вычислительной библиотекой, и вы ОЧЕНЬ ДЕЙСТВИТЕЛЬНО хотите использовать метод копирования и загрузки копий, вы можете создать жесткие ссылки, чтобы избежать дублирования реального DLL-файла.(fsutil hardlink create на Win7 или Vista)

0 голосов
/ 19 ноября 2010

Как вы уже поняли, вы не можете загрузить библиотеку несколько раз.Я полагаю, у вас есть две возможности:

В обоих решениях необходимо рассмотреть метод обмена данными между процессами / доменами приложений.Во всяком случае, это не будет простой задачей!

...