pthread_cancel/pthread_join, Milana, 08-Июл-05, 14:10 [смотреть все]Всем здравствуйте!Помогите пожалуйста разобраться с таким вопросом: в контейнере типа list<...*> у меня храняться указатели на объекты, в которых есть public data member pthread_t. В обработчике сигнала sigterm основного потока рассылаю всем нитям нечто на подобии for_each(..., ..., cancelThread ); и жду когда все завершатся- for_each( ..., ..., joinThread ); inline (cancel/join)Thread( ...* p ) { pthread_(cancel/join)( p->(поле) ); } Код не точный, но смысл сохранен. Так вот, грабли в том, что cancel корректно (судя по возвращаемым значениям) рассылается, а на первом join'е все встрявает. Если посылаешь второй такой же сигнал, cancel рассылается с кодом возврата 3, но join тогда проходит Ok. os- FreeBSD5.3,cc- gcc 3.4.2 |
- pthread_cancel/pthread_join, DeadMustdie, 19:49 , 08-Июл-05 (1)
Вообще ждать завершения потоков в обработчике сигналов глубоко неправильно. Равно как и применять pthread_cancel() в программе на C++, поскольку деструкторы созданных на стеке объектов при этом не отработают. Что при использовании STL гарантирует утечки памяти.Причины описанной проблемы могут быть разные, всё сильно зависит от кода поточных функций и кода главного потока. Советую передачу команды на завершение потоков реализовать путём установки специального значения в переменную типа 'volatile int', а остановки потоков ожидать в главном потоке. Переход к нужный режим можно реализовать на основе pthread_cond_wait() & friends, условие инициировать в обработчике сигналов.
- pthread_cancel/pthread_join, Milana, 21:46 , 08-Июл-05 (2)
>Вообще ждать завершения потоков в обработчике сигналов глубоко неправильно.Если не секрет, по какой причине? А то я предвижу аналогичную проблему с sighup.
- pthread_cancel/pthread_join, DeadMustdie, 22:49 , 08-Июл-05 (3)
>Если не секрет, по какой причине? А то я предвижу аналогичную проблему >с sighup. На код обработчика сигналов накладывается очень много ограничений. Всё время, которое поток проводит в обработчике сигналов, этот поток не может обрабатывать другие сигналы. В не совсем прямых реализациях POSIX-потоков тем самым можно вообще заблокировать всю обработку сигналов процессом, а при таком раскладе вновь поступающие сигналы вообще не будут обрабатываться. В некоторых случаях это блокирует насмерть часть функций стандартной библиотеки C. Моя обычная практика заключается в запрете обработки сигналов вообще всеми потоками и запуске дополнительного потока, содержащего циклический вызов sigwait(). По крайней мере, здесь можно гарантировать аккуратный захват и освобождение всех необходимых блокировок и, тем самым, гарантировать целостность общих для всех потоков структур данных. А в обработчике сигналов можно очутиться на середине обновления какой-либо используемой в нём структуре - после чего обычно с небес валится SIGSEGV. Причём поди пойми, из-за чего.
- pthread_cancel/pthread_join, Vladislav Lazarenko, 14:17 , 09-Июл-05 (4)
>>Если не секрет, по какой причине? А то я предвижу аналогичную проблему >>с sighup. > >На код обработчика сигналов накладывается очень много ограничений. >Всё время, которое поток проводит в обработчике сигналов, этот поток >не может обрабатывать другие сигналы. В не совсем прямых реализациях >POSIX-потоков тем самым можно вообще заблокировать всю обработку >сигналов процессом, а при таком раскладе вновь поступающие сигналы >вообще не будут обрабатываться. В некоторых случаях это блокирует >насмерть часть функций стандартной библиотеки C. > >Моя обычная практика заключается в запрете обработки сигналов вообще >всеми потоками и запуске дополнительного потока, содержащего циклический >вызов sigwait(). По крайней мере, здесь можно гарантировать аккуратный >захват и освобождение всех необходимых блокировок и, тем самым, >гарантировать целостность общих для всех потоков структур данных. >А в обработчике сигналов можно очутиться на середине обновления >какой-либо используемой в нём структуре - после чего обычно с >небес валится SIGSEGV. Причём поди пойми, из-за чего. pthread_cancel - от лукавого...
- pthread_cancel/pthread_join, Milana, 13:09 , 11-Июл-05 (5)
>pthread_cancel - от лукавого... А почему он так Вам ненравится? Я просто не очень хочу нагружать потоковые функции различными флагами и проверками по сути не относящимися к их основной задаче. Тогда возникает вопрос- как сообщитьь нитям, что они должны сворачивать свою деятельность. Что касается критических мест в потоках, то их можно защитить pthread_setcancelstate. А если понадобятся автоматические объекты, то их можно тоже поместить в такую секцию, которая выполнится до конца и обеспечит выполнение всех деструкторов.
|