2010-01-18 3 views

ответ

50

Первый магазин идентификатор потока

pthread_create(&thr, ...) 

потом называют

pthread_cancel(thr) 

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

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

+4

Проблема с pthread_cancel, btw, заключается в том, что если вы ее используете, тогда код, выполняющийся в отключенном потоке, должен понимать точки отмены и следить за тем, чтобы (a) он ударил достаточно часто, чтобы он фактически был отменен в хорошем состоянии и (б) он не утечка ресурсов, когда это произойдет. Это довольно сложно, в то время как если вы используете сообщение, тогда он четко отображается в вашем коде точно, когда поток может выйти. –

+11

@Steve: К сожалению, 'pthread_cancel' является единственным чистым способом * в библиотечном коде *, чтобы прервать поток, который может быть заблокирован в syscall. Другой метод заключается в установке прерывания обработчика сигнала и убедитесь, что весь ваш код готов к работе с 'EINTR', но библиотечный код не может считать, что он имеет право изменять обработку сигнала или накладывать обработку« EINTR »на вызывающего. –

2

Посмотрите на функцию pthread_kill().

+2

Это не убивает нить, она просто посылает сигнал. – alk

5

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

18

Существует два подхода к этой проблеме.

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

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

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

0
pthread_exit(0) 

Это убьет нить.

Смежные вопросы