Убить поток в библиотеке Pthread

Я использую pthread_create(&thread1, &attrs, //... , //...); и мне нужно, если возникнет какое-то условие, нужно убить этот поток, как это убить?


person Sajad Bahmani    schedule 18.01.2010    source источник


Ответы (5)


Сначала сохраните идентификатор потока

pthread_create(&thr, ...)

тогда позже позвоните

pthread_cancel(thr)

Однако это не рекомендуемая практика программирования! Лучше использовать механизм межпотоковой связи, такой как семафоры или сообщения, чтобы сообщить потоку, что он должен остановить выполнение.

Обратите внимание, что pthread_kill (...) на самом деле не завершает принимающий поток, а вместо этого доставляет ему сигнал, и это зависит от сигнала и обработчиков сигналов, что происходит.

person Antti Huima    schedule 18.01.2010
comment
Проблема с pthread_cancel, кстати, заключается в том, что если вы его используете, то код, работающий в потоке, который был отменен, должен понимать точки отмены и убедиться, что (а) он попадает в одну достаточно часто, чтобы он действительно был отменен вовремя и (б) при этом не происходит утечки ресурсов. Это довольно сложно, тогда как если вы используете сообщение, то в вашем коде четко указывается, когда поток может выйти. - person Steve Jessop; 18.01.2010
comment
@Steve: К сожалению, pthread_cancel - единственный чистый способ в коде библиотеки прервать поток, который может быть заблокирован системным вызовом. Другой метод - установить обработчик сигнала прерывания и убедиться, что весь ваш код подготовлен к работе с EINTR, но код библиотеки не может предполагать, что он имеет право изменять обработку сигнала или накладывать EINTR обработку на вызывающего. - person R.. GitHub STOP HELPING ICE; 24.03.2011

Есть два подхода к этой проблеме.

  • Используйте сигнал: поток устанавливает обработчик сигнала, используя sigaction(), который устанавливает флаг, и поток периодически проверяет флаг, чтобы увидеть, должен ли он завершиться. Когда поток должен завершиться, подайте ему сигнал с помощью pthread_kill() и дождитесь его завершения с помощью pthread_join(). Этот подход требует предварительной синхронизации между родительским потоком и дочерним потоком, чтобы гарантировать, что дочерний поток уже установил обработчик сигнала, прежде чем он сможет обработать сигнал завершения;
  • Используйте точку отмены: поток завершается всякий раз, когда выполняется функция отмены. Когда поток должен завершиться, выполните pthread_cancel() и дождитесь его завершения с помощью pthread_join(). Этот подход требует подробного использования pthread_cleanup_push() и pthread_cleanup_pop(), чтобы избежать утечки ресурсов. Эти последние два вызова могут нарушить лексическую область видимости кода (поскольку это могут быть макросы, дающие токены { и }), и их очень трудно поддерживать должным образом.

(Обратите внимание, что если вы уже отсоединили поток, используя pthread_detach(), вы не можете присоединиться к нему снова, используя pthread_join().)

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

person alecov    schedule 02.07.2011

Я согласен с Антти, лучшей практикой было бы реализовать некоторые контрольные точки, где поток проверяет, должен ли он завершаться. Эти контрольные точки могут быть реализованы несколькими способами, например: общая переменная с блокировкой или событие, которое поток проверяет, установлен ли он (поток может выбрать нулевое время ожидания).

person Fredrik Jansson    schedule 18.01.2010
comment
В большинстве случаев это абсолютно правильно. Однако во многих ситуациях это просто нецелесообразно. Например, мой текущий проект - это минимальный текстовый редактор, в котором у меня есть выделенный поток для получения пользовательского ввода. Поскольку getch() работает синхронно, мой входной поток не сможет обнаружить, что он должен завершиться, пока пользователь не нажмет другую клавишу. Это был бы очень плохой дизайн. Поскольку потоку пользовательского ввода никогда не нужно выделять дополнительные ресурсы, гораздо лучше убить его с помощью pthread_cancel(). - person ; 12.05.2020

Взгляните на функцию pthread_kill().

person Wyzard    schedule 18.01.2010

pthread_exit(0) 

Это убьет поток.

person Anand Paul    schedule 02.02.2018
comment
Это неверный ответ. pthread_exit () - это функция, используемая для завершения потока, в котором эта функция вызывается. Это правильное завершение. pthread_exit () не может использоваться для воздействия на какой-либо другой поток. Пожалуйста, не вводите в заблуждение. - person Animesh Kumar; 25.10.2020