Допустим, какой-то поток (не известно, где создан) вызвал мою функцию Как отследить его завершение (желательно аварийное тоже) минимальными усилиями? Желательно для главного потока делать такую же логику. Фоновых потоков желательно не создавать В POSIX это делается макросом pthread_cleanup_push
Не совсем понимаю задачу. Если просто нужно получить факт того, что поток завершился, то можно получить его хендл и ждать на WaitForSingleObject. Если нужно предотвратить аварийное завершение потока, то в той твоей функции поставить обработчик SEH. Если нужно предотвратить штатное завершение потока, то можно похукать ExitThread.
Хукать нельзя. Приложение должно работать в Windows Services, а там вроде хуки не проходят. Если очень упрощено - задача в том, чтобы инициализировать и финализировать TLS переменные корректно. WaitForSingleObject нужно делать в другом потоке, хотелось бы обойтись без использования дополнительных потоков.
Я экспериментировал с хуками, в обычно приложении они работают, а в сервисах нет Не хотелось бы акцентировать на этом внимание Кстати в Dll есть калбеки с DLL_THREAD_DETACH Хотелось бы иметь что-то подобное
Этот колбек будет вызван только, если поток выйдет нормально, без эксепшена. --- Сообщение объединено, 1 июн 2020 --- Такое бывает, когда хуки сделаны кривыми руками.
Поток завершается ядром, это значит что никаких событий в процессе не происходит(на стороне юмод). Если поток крэшнул - возникло исключение, то работает стандартный механизм ловушек. Если он пал в глобальных крит структурах, то процесс вообще работать не может, его прикончит ядро и никаких сообщений не будет.
Совершенно верно, это абсолютно то, что нужно! Только у меня не VS, у меня модуль компилируется в Clang, а линкуется в Delphi/FreePascal Тут наверное может быть две траблы: 1. Не нахожу аналогичный код для Clang/GCC, подскажете, как это там выглядит? Пробовал такое, не сработало: Код (Text): #pragma data_seg(".CRT$XLY") void* p_thread_callback = my_tls_callback; #pragma data_seg() 2. В теории можно получить объектники для Win32/64 в той же студии, но Delphi/FreePascal может не прилинковать эти секции. Судя по коду там нужно линкеру явно указать какие-то опции. Может протестируем этот сценарий? Соберите, пожалуйста, кто-нибудь объектник для Win64, который будет вызывать внешнюю функцию tls_test() без аргументов. --- Сообщение объединено, 1 июн 2020 --- Судя по описанию может подойти. Только смущает: 1. Нужно переводить поток в Fiber 2. Связываться с COM 3. Появилась в винде относительно недавно "Стандартная" финализация TLS меня вполне устроит
DevilDevil, Если поток крэшит, то вызывается не загрузчик в котором какие то тлс, а обратный ядерный вызов для сообщения про фаулт, затем после двух попыток обработки процесс будет прибит. Тупо загрузи длл и смотри dll_detach. Это сработает лишь при штатном добровольном завершении потоков.
Меня это устраивает Но если можешь посоветовать грамотный хук - я с удовольствием послушаю Ещё я думаю, что может быть существует какой-то отложенный ивент, типа IOCP, который будет вызван в случае поток отработает?
1. Ничего не нужно. Просто вызывай FlsAloc, FlsSetValue. 2. С COM не нужно связываться. 3. Фиберы уже давно в винде.
DevilDevil, > IOCP, который будет вызван в случае поток отработает? Просто вот смотри, крэшнул тред, к примеру его стек покоцался и ядро не сможет послать нотифи в юзер - прикончит процесс; в старших версиях все структуры охраняются, если они не связаны вызывается ядро(int29) и сразу процесс прикончится. Это значит что ждущие потоки в том же процессе никогда не дождуться, а будут завершены, сразу все. Поэтому нужен как минимум второй мониторящий процесс. Древний штатный механизм - отладочные порты.
Зачем мне нештатная ситуация? Меня интересуют в первую очередь штатные средства. И желательно минимальными ресурсами
DevilDevil, А чем же интересны штатные завершения тредов, даже представить не могу. Это нужно для анализа ошибок, крэши/деадлоки/утечки/статистика. А зачем нужно мониторить exitthread
Я пишу менеджер памяти, который привязан к TLS. Нужно грамотно обрабатывать случаи, когда поток завершается
Это решается, если все потоки создаются и уничтожаются твоими библиотечными функциями (как, например, в случае библиотеки pthread). Если же поток уничтожается сервисами системы напрямую, отследить его нельзя. И все менеджеры памяти основываются на том, что пользователь будет использовать лишь предоставляемые менеджером функции.
Действительно FlsAlloc/FlsSetValue хорошо работает, главное - задать значение отличное от NULL Но оно работает начиная с Vista, а мне хотелось бы поддерживать XP Может скомпилирует кто-то объектник под Win64 стандартным образом, который я попробую заюзать в Delphi? --- Сообщение объединено, 1 июн 2020 --- А разве в POSIX можно создать поток не из pthread.h?
А к чему внутри сводится pthread? К системным вызовам в ядро линукса. Если не ошибаюсь, clone, который в ядре сводится к do_fork. И что помешает пользователю сделать этот сисколл?