The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]




Версия для распечатки Пред. тема | След. тема
Новые ответы [ Отслеживать ]
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. А если понадобятся автоматические объекты, то их можно тоже поместить в такую секцию, которая выполнится до конца и обеспечит выполнение всех деструкторов.




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2025 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру