Присоединение к потоку, запущенному DLL, до завершения программы в WindowsC++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Присоединение к потоку, запущенному DLL, до завершения программы в Windows

Сообщение Anonymous »

Справочная информация
Я использую библиотеку miniaudio для реализации аудиомодуля в библиотеке SFML 3.x с открытым исходным кодом.
В попытке упростить управление нашими аудиоресурсами я удалил подсчет ссылок во время выполнения вместо более простого статического объекта-менеджера (см. SFML/pull/2974). >
Мои изменения вызвали проблемы в Windows: любое приложение, использующее аудиомодуль, зависает при завершении работы. После некоторого расследования, проведенного @binary1248, и некоторых дополнительных тестов мной, мы поняли, что проблема связана с тем, как Windows обрабатывает atexit и завершение потока при сборке в виде DLL (общая библиотека). Подробнее см. в этой статье.
По сути, в рамках процедуры завершения процесса среда выполнения Win32 принудительно завершает любой оставшийся поток, не присоединяясь к ним и не отправляя уведомление об отключении потока. Это означает, что попытка очистить ресурсы miniaudio с помощью atexit (именно так вызываются деструкторы статических объектов C++) приведет к зависанию программы на условной переменной подождите во внутренних устройствах miniaudio (

Код: Выделить всё

ma_event_wait(&pDevice->stopEvent)
внутри ma_engine_uninit), поскольку pDevice->thread был завершен и не было возможности сигнализировать о событии остановки.
В качестве обходного пути я попробовал проверить, жив ли поток, прежде чем ждать, используя это решение, которое предполагает, что достаточно проверить WaitForSingleObject(threadHandle, 0) == WAIT_TIMEOUT. Хотя это решило проблему на моем компьютере, это не помогло на других установках Windows, и я все равно считаю, что это неопределенное поведение.
Я хотел бы чисто присоединиться к miniaudio' внутренние потоки s перед завершением работы программы. Как это сделать?
Проблема
Насколько я понимаю, происходит следующее:
< ol>
[*]Общая DLL SFML инициализирует miniaudio, который внутри порождает некоторые рабочие потоки.
[*]После завершения процесса функция atexit процесса стек обрабатывается.
  • Здесь нет ничего полезного, поскольку очистка miniaudio зарегистрирована в общем стеке функций atexit SFML.
[*]

Код: Выделить всё

ExitProcess
вызывается, и все потоки, кроме основного, принудительно завершаются без какого-либо уведомления об отключении потока.
  • Это включает рабочие потоки miniaudio. li>
[*]Библиотека SFML DLL выгружается и обрабатывает собственный стек функций atexit, который вызывает miniaudio' s очистка.
  • В этом проблема!
  • Теперь уже слишком поздно для процедуры очистки. присоединиться к рабочим потокам, поэтому он будет зависать на неопределенный срок в ожидании условной переменной, которая больше не существует.

Вопрос
Можно ли, даже модифицировав сам miniaudio, чисто присоединяться к рабочим потокам при завершении программы, даже если эти потоки были запущены из общей библиотеки?
В принципе, можно ли вызвать процедуру очистки miniaudio до того, как произойдет ExitProcess? p>
Если нет, то можно ли как-то добиться желаемого результата, не требуя от разработчика приложения вручную вызывать функцию очистки в конце основного?
Пример

Код: Выделить всё

// main.cpp
#include 
#include "dll.h"

int main()
{
std::cout 

Подробнее здесь: [url]https://stackoverflow.com/questions/78507797/joining-a-thread-started-by-a-dll-prior-to-program-termination-on-windows[/url]
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C++»