Освобождение ресурсов при выгрузке dll
От: nekoriu Россия  
Дата: 19.02.21 14:46
Оценка:
Здравствуйте.

Нужно освободить ресурсы при выгрузке dll. В том числе завершить поток, который был создан в dll. Это нужно сделать в DllMain().
Поток может зависнуть на одной из функций секунд на 10. Нужно сначала завершить поток, а дальше освобождать память, закрывать хэндлы.

Пробовал дождаться завершения операции потоком, проверяя общую переменную. Синхронизация потоков через mutex. Завершение операции не наступает. В документации предупреждали, что в DllMain() нельзя заниматься синхронизацией потоков.

Пробовал завершить поток с помощью TerminateThread(). Завершается успешно, но после этого зависание на delete obj.

Есть идеи?
Re: Освобождение ресурсов при выгрузке dll
От: Carc Россия https://vk.com/gosha_mazov
Дата: 19.02.21 15:19
Оценка:
Здравствуйте, nekoriu, Вы писали:

N>Здравствуйте.


N>Нужно освободить ресурсы при выгрузке dll. В том числе завершить поток, который был создан в dll. Это нужно сделать в DllMain().

N>Поток может зависнуть на одной из функций секунд на 10. Нужно сначала завершить поток, а дальше освобождать память, закрывать хэндлы.

N>Пробовал дождаться завершения операции потоком, проверяя общую переменную. Синхронизация потоков через mutex. Завершение операции не наступает. В документации предупреждали, что в DllMain() нельзя заниматься синхронизацией потоков.


N>Пробовал завершить поток с помощью TerminateThread(). Завершается успешно, но после этого зависание на delete obj.


N>Есть идеи?

А кто создает поток в DLL? Код потока свой? Может ему передать какой-нить event, для синхронизации с основным приложением на предмет давай завершайся?
Aml Pages Home
Re: Освобождение ресурсов при выгрузке dll
От: ononim  
Дата: 19.02.21 16:39
Оценка: +1
N>Пробовал завершить поток с помощью TerminateThread(). Завершается успешно, но после этого зависание на delete obj.
N>Есть идеи?
возможны разные хаки, но правильнее всего — сделать экспортную функцию Finalize которую дергать до FreeLibrary
Как много веселых ребят, и все делают велосипед...
Re[2]: Освобождение ресурсов при выгрузке dll
От: nekoriu Россия  
Дата: 20.02.21 06:57
Оценка:
C>А кто создает поток в DLL? Код потока свой? Может ему передать какой-нить event, для синхронизации с основным приложением на предмет давай завершайся?

Поток создаю я. В планах попробовать из потока dll сообщить пользовательскому потоку "я завершился" с помощью event. Поток из dll может зависнуть секунд на 10 на функции из wininet.
Re[2]: Освобождение ресурсов при выгрузке dll
От: nekoriu Россия  
Дата: 20.02.21 06:59
Оценка:
O>возможны разные хаки, но правильнее всего — сделать экспортную функцию Finalize которую дергать до FreeLibrary
Заказчик хочет, чтобы Finalize, вызывалась автоматически при вызове FreeLibrary.
Re[3]: Освобождение ресурсов при выгрузке dll
От: Carc Россия https://vk.com/gosha_mazov
Дата: 20.02.21 07:43
Оценка:
Здравствуйте, nekoriu, Вы писали:

C>>А кто создает поток в DLL? Код потока свой? Может ему передать какой-нить event, для синхронизации с основным приложением на предмет давай завершайся?


N>Поток создаю я. В планах попробовать из потока dll сообщить пользовательскому потоку "я завершился" с помощью event. Поток из dll может зависнуть секунд на 10 на функции из wininet.


Что то я не понял!?! Поток в DLL, который может долго завершаться, создается в самой DLL? И код создания потока в самой DLL, то же Ваш?
Можно его менять?

Если весь код Ваш, то вариантов только два
1) Поток, в котором выполняется DLLMain и поток который создается внутри ДЛЛ должны как то синхронизироваться. Т.е. поток из коорого выполняется DLLMain, должен как-то сказать этому фоновому потоку давай завершайся. И соответственно этот фоновый поток должен периодически проверять какой-нить примитив синхронизации вроде эвента, а не пора ли на выход...

2) Ну как правильно сказал ononim должна быть экспортная функция Finalize, чтобы вызывающий код из самого внешнего exe-процесса четко понимал, что завершение этого Finalize может занять время. Что делать в вызывающем коде с таким ожиданием другой разговор (путь хоть таймер с обратным отчетом, и кнопкой "Не ждать — завершить сейчас".

Тут как бы в таком случае всё очевидно и детерминировано для вызывающего кода.
В DLLMain все те же проблемы, все те же ожидания завершения и.т.л. Только а) ничего совсем не очевидно, что там какой-то фоновый поток еще в DLL завершаться будет б) никакого пространства для творчества — прототип DllMain определен, и все (вызывающий код) ожидают вполне определенное поведение.

А вообще это называется *авно-дизайн!!!
Кто что там нараспределял, позапускал (хендлы, память), тот за то и отвечает. А так все эти левые фоновые потоки, которые создаются в DLL, какие-то невидимки. Зомби просто... Чего то там делают, информации о них наружу почти что ноль, но взаимодействовать с ними надо.. Надо как-то иначе проектировать такую ситуацию.
Aml Pages Home
Re[4]: Освобождение ресурсов при выгрузке dll
От: nekoriu Россия  
Дата: 20.02.21 08:45
Оценка:
C>Что то я не понял!?! Поток в DLL, который может долго завершаться, создается в самой DLL? И код создания потока в самой DLL, то же Ваш?
C>Можно его менять?

C>Если весь код Ваш, то вариантов только два

C>1) Поток, в котором выполняется DLLMain и поток который создается внутри ДЛЛ должны как то синхронизироваться. Т.е. поток из коорого выполняется DLLMain, должен как-то сказать этому фоновому потоку давай завершайся. И соответственно этот фоновый поток должен периодически проверять какой-нить примитив синхронизации вроде эвента, а не пора ли на выход...

C>2) Ну как правильно сказал ononim должна быть экспортная функция Finalize, чтобы вызывающий код из самого внешнего exe-процесса четко понимал, что завершение этого Finalize может занять время. Что делать в вызывающем коде с таким ожиданием другой разговор (путь хоть таймер с обратным отчетом, и кнопкой "Не ждать — завершить сейчас".


C>Тут как бы в таком случае всё очевидно и детерминировано для вызывающего кода.

C>В DLLMain все те же проблемы, все те же ожидания завершения и.т.л. Только а) ничего совсем не очевидно, что там какой-то фоновый поток еще в DLL завершаться будет б) никакого пространства для творчества — прототип DllMain определен, и все (вызывающий код) ожидают вполне определенное поведение.

C>А вообще это называется *авно-дизайн!!!

C>Кто что там нараспределял, позапускал (хендлы, память), тот за то и отвечает. А так все эти левые фоновые потоки, которые создаются в DLL, какие-то невидимки. Зомби просто... Чего то там делают, информации о них наружу почти что ноль, но взаимодействовать с ними надо.. Надо как-то иначе проектировать такую ситуацию.
Поток, который может долго завершаться, создается в Dll. Сам его создаю, код потока мой.
Re[5]: Освобождение ресурсов при выгрузке dll
От: Carc Россия https://vk.com/gosha_mazov
Дата: 20.02.21 09:09
Оценка:
Здравствуйте, nekoriu, Вы писали:


C>>А вообще это называется *авно-дизайн!!!

C>>Кто что там нараспределял, позапускал (хендлы, память), тот за то и отвечает. А так все эти левые фоновые потоки, которые создаются в DLL, какие-то невидимки. Зомби просто... Чего то там делают, информации о них наружу почти что ноль, но взаимодействовать с ними надо.. Надо как-то иначе проектировать такую ситуацию.
N>Поток, который может долго завершаться, создается в Dll. Сам его создаю, код потока мой.

Ну тогда соответственно только синхрониться с фоновым потоком, из основного потока в котором работает DllMain

Согласно вот этому, Вами же и озвученному

Нужно освободить ресурсы при выгрузке dll. В том числе завершить поток, который был создан в dll. Это нужно сделать в DllMain().
Поток может зависнуть на одной из функций секунд на 10. Нужно сначала завершить поток, а дальше освобождать память, закрывать хэндлы.


Фигня какя-то в дизайне? Почему надо сначала завершить фоновый поток, а только потом освобождать ресурсы (память, хендлы)?
Кто эти ресурсы распределял? Поток в котором работает DllMain, или этот фоновый поток?
Если фоновый поток распределял, то пусть он же и освобождает. Если, распределял поток ДллМайн, то зачем ему ждать завершения фонового потока?

Что то тут не до в консерватории...
По уму кто распределял, тот поток и должен освобождать. Распределителю всегда лучше знать, что он и как распределил, и когда можно это освободить.

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

А откуда фоновому потоку узнать, что ресурсы ему переданные из основного потока в момент Икс протухли и освободились? А фоновый поток ресурсы
эти всё еще использует?

Тут или синхронизация должна быть между потоками. Или что нить вроде shared_ptr, который сам все удалит, когда счетчик использования ресурсов обнулится.

А вообще нужны подробности постановки задачи. Вроде как аккурат попахивает неправильным дизайном, неверным проектированием.
Aml Pages Home
Отредактировано 20.02.2021 9:12 Carc . Предыдущая версия . Еще …
Отредактировано 20.02.2021 9:10 Carc . Предыдущая версия .
Re[3]: Освобождение ресурсов при выгрузке dll
От: ononim  
Дата: 20.02.21 17:04
Оценка:
O>>возможны разные хаки, но правильнее всего — сделать экспортную функцию Finalize которую дергать до FreeLibrary
N>Заказчик хочет, чтобы Finalize, вызывалась автоматически при вызове FreeLibrary.
А как насчет варианта, что при запуске потока длл будет делать LoadLibrary сама на себя, а поток будет гулять сам по себе, но выходить через FreeLibraryAndExitThread.
Получится что FreeLibrary не всегда будет приводить к реальной выгрузке длл.. А нужна ли эта реальная выгрузка?
Как много веселых ребят, и все делают велосипед...
Re: Освобождение ресурсов при выгрузке dll
От: morgot  
Дата: 27.02.21 16:58
Оценка:
Здравствуйте, nekoriu, Вы писали:

N>Здравствуйте.


N>Нужно освободить ресурсы при выгрузке dll. В том числе завершить поток, который был создан в dll. Это нужно сделать в DllMain().

N>Поток может зависнуть на одной из функций секунд на 10. Нужно сначала завершить поток, а дальше освобождать память, закрывать хэндлы.

FreeLibraryAndExitThread не подойдет? Или что-то повесить в DLL_PROCESS_DETACH
Re: Освобождение ресурсов при выгрузке dll
От: nekoriu Россия  
Дата: 03.03.21 14:59
Оценка:
Всем спасибо. Пока этой темой не занимаюсь. Остановился на явном вызове Finalize. У меня были проблемы при потоковой синхронизации в DllMain, при использовании wininet в DllMain, как и обещали в документации.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.