2011-02-17 2 views
4

У меня есть старая библиотека C++, которая была разработана для использования в однопоточных средах.Как использовать старую однопоточную библиотеку C++ в многопоточной среде

В библиотеке представлены интерфейсы для инициализации, которые изменяют внутренние структуры данных библиотеки и используют ее, которая только считывает данные и производит вычисления.

Моя цель - использовать эту библиотеку в многопоточном приложении Windows с разными потоками, вызывающими экземпляры DLL, инициализированной различными данными.

Предполагая, что переписывание DLL, чтобы разрешить многопоточность, было бы запретительным, существует ли способ разрешить несколько экземпляров DLL в одном процессе с отдельными пространствами памяти или получить аналогичный результат другими способами?

+0

Еще одна идея, которая могла бы быть интересной, - использовать разные AppDomains, создавая ее с каждым экземпляром библиотеки и загружая ее в нее: AppDomains предоставляет отдельные пространства памяти и может быть выгружен, освобождая память процесса и загруженный сборки внутри. –

ответ

6

Если DLL содержит статические ресурсы, то они будут совместно использоваться для всех созданных экземпляров.

Одним из возможных способов было бы создание единого экземпляра и ограничение доступа к нему с использованием какого-либо механизма блокировки. Это может снизить производительность в зависимости от использования, но без изменения внутренней структуры DLL может быть сложно работать с несколькими экземплярами.

+5

Я согласен с общей идеей, но будьте осторожны, что она все равно может пойти не так, если dll использует потоковое локальное хранилище. Поскольку он разработан однопоточно, он не будет использовать TLS * специально, но он может использовать его косвенно через зависимость. Поэтому, если вы настроите один поток, вы можете обнаружить, что вызовы из другого потока не работают. Следующий уровень обертки вместо просто блокировки, создайте поток, единственной целью которого является управление этой DLL, и доступ ко всем функциям dll, отправив сообщения в этот поток и ожидая ответов. –

+0

@Steve Jessop: это была моя первая идея, но в этом случае я мог инициализировать DLL только с одним набором данных за раз: идеальное решение позволило бы иметь разные параметры инициализации для каждого потока одновременно. –

+2

@Coffee: ah, извините, я не понял, что не только DLL не поддерживает несколько потоков, но также имеет глобальные данные, которые по сути вы хотите быть специфичными для дескриптора. Я уверен, что вы можете клонировать dll грубой силой - переименуйте его, а затем получите доступ к нему только через LoadLibrary/GetProcAddress, а не путем связывания. Это действительно хорошо для фиксированного количества копий, хотя я не уверен, что вы хотите, чтобы ваш исполняемый файл выбирал новое имя для dll на лету. Может работать до тех пор, пока машина не заперта, но отчетливо взламывается. –

5

Совместное использование статических ресурсов между всеми потоками, подключенными к одной DLL внутри процесса, замышляет вас здесь.

Однако есть хитрость для достижения этой цели. До тех пор, пока библиотеки DLL имеют разные имена, система считает их разными, и поэтому создаются отдельные экземпляры кода и данных.

Чтобы достичь этого, для каждого потока скопируйте DLL во временный файл и загрузите с него LoadLibrary. Вы должны использовать явное связывание (GetProcAddress), а не файлы lib, но это действительно единственный способ.

+2

Вариантом будет DLL-оболочка, предоставляющая один и тот же интерфейс, но использующая локальное хранилище потоков для переадресации каждого вызова на поточную копию DLL. Это изолирует все обманки в DLL обертки. – MSalters

+0

@Salters милая идея! –

 Смежные вопросы

  • Нет связанных вопросов^_^