Вопрос по windows, multithreading, c++ – Выход из потока при удалении статического объекта во время выгрузки DLL вызывает взаимоблокировку?

6

У меня есть один экземпляр (глобальный / статический объект) ClassA внутри моей DLL с задержкой загрузки. Этот объект внутри имеет "Наблюдатель" нить, необходимая для корректного отключения. Когда я вызывал FreeLibrary, я заметил, что во время удаления этого статического объекта мой поток запрашивал отключение, но зависает на _endthreadex () и вызывает взаимоблокировку. Не имеет значения, вызываю ли я _endthreadex явно или неявно. Не имеет значения, является ли объект глобальным или статическим - тот же результат. Этот поток обернут в ClassB (реализован по шаблону с пользовательским циклом сообщений). Существует запрос на отключение потока (сообщение) и следующий за WaitForSingleObject, который никогда не возвращается для данного потока heandle.

Тот же «класс потока шаблона» используется везде в коде и прекрасно работает выключение. Единственная проблема при удалении статического объекта. Я думаю, что есть некоторая блокировка внутри _endthreadex (), которая уже заблокирована при выгрузке dll и удалении статических объектов.

Тема началась с _beginthreadex. пс. Когда я создаю тот же статический объект внутри приложения - приложение закрывается без каких-либо существенных проблем.

Есть идеи, почему _endtreadex вызывает тупик? Как этого избежать?

@ dave Спасибо. Это объясняет, что я получил ... adspx5
Не делайanything scary в вашемDllMain, Глобальные объекты создаются / разрушаются в DllMain. Luke
Блокировки, как правило, довольно легко диагностировать, вы можете потратить время на то, чтобы использовать Debug + Break All для взлома отладчика. Просмотр следов стека дает важные подсказки. Обязательно включите сервер символов отладки. Hans Passant
Из документа для DllMAin -Because DLL notifications are serialized, entry-point functions should not attempt to communicate with other threads or processes. Deadlocks may occur as a result.       В общем, вы не можете сделать многое во время завершения DLL. dave

Ваш Ответ

1   ответ
5

блокировка загрузчика, чтобы он мог вызывать DllMain с помощью DLL_THREAD_DETACH. Однако поток, который вызвал FreeLibrary, уже удерживает блокировку загрузчика, поскольку вы уже находитесь в середине вызова DllMain с DLL_PROCESS_DETACH.

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

Наилучшим подходом, вероятно, является создание явных функций InitializeLibrary () и UninitializeLibrary () для вызова пользователем.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded adspx5

Похожие вопросы