WaitForSingleObject для потока зависает при вызове из глобалов приложения

#multithreading #winapi #waitforsingleobject

#многопоточность #winapi #waitforsingleobject

Вопрос:

Я создаю поток как часть некоторого пула, который необходимо уничтожить, когда приложение (фактически DLL) завершается. Итак, у меня есть некоторые «глобальные переменные», то есть структура, созданная глобально статически, и в деструкторе она освобождает все созданные потоки и ожидает их с помощью WaitForSingleObject . К сожалению, это зависает навсегда, и проверка в отладчике показывает, что потоки все еще существуют, просто застряли где-то в системных библиотеках DLL. Когда я вызываю это до того, как глобалы будут выпущены, тогда все идет нормально. Я не вижу никаких упоминаний об этом в документах Win32. Есть идеи?

Комментарии:

1. деструктор, вызываемый из точки входа dll, внутри критической секции блокировки загрузчика. поток, перед выходом, попробуйте также войти в этот критический раздел для отправки DLL_THREAD_DETACH . но не может, потому что он удерживается потоком, который вызывает WaitForSingleObject .

2. таким образом, ваш поток не может завершиться, пока ваш WaitForSingleObject не завершится, но WaitForSingleObject может завершиться, пока ваш поток не завершится. скорее всего, вам не нужно ждать. когда вы создаете поток из dll — вам нужна ссылка ad на dll. и поток должен завершиться FreeLibraryAndExitThread вызовом. ждать выхода из потока не нужно — для чего ?! вам нужен только сигнальный поток для выхода, и это вы уже делаете, как я понимаю

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

4. но я просто объясню вам, почему это тупик

5. Рекомендации по использованию библиотеки динамических ссылок . Убедитесь, что вы понимаете, когда выполняются ваши глобальные конструкторы и деструкторы.

Ответ №1:

Таким образом, решение действительно состоит в том, чтобы избежать ожидания и фактически выпустить что-либо в DllMain (включая глобальные переменные), это плохо, поэтому нужно выпустить все важное раньше. Иногда это немного сложно, когда дело доходит до библиотек DLL, но хорошо…

Комментарии:

1. Я рад, что вы получили свое решение, и спасибо за то, что поделились, я был бы признателен, если бы вы отметили их как ответ, и это будет полезно для другого сообщества.