Для pthread, Как убить дочерний поток из основного потока - PullRequest
19 голосов
/ 29 сентября 2010

Я использую pthread_create для создания нескольких дочерних потоков. За один раз основной поток хочет уничтожить все дочерние потоки, иначе будет сегмент falut. Какую функцию я должен использовать, чтобы закончить это? Я искал ответ от Google и получил функцию, как pthread_kill. Но я не знал, какой сигнал я должен отправить дочернему потоку, чтобы убить их. Моя рабочая среда - RHEL 5.4, а язык программирования - C.

Ответы [ 4 ]

25 голосов
/ 29 сентября 2010

В общем, вы не хотите насильственно уничтожать дочернюю нить, но вместо этого вы хотите попросить ее прекратить. Таким образом, вы можете быть уверены, что ребенок покидает безопасное место и все его ресурсы вычищены.

Обычно я делаю это с небольшим фрагментом общего состояния между родителем и потомком, чтобы родитель мог передать «запрос на выход» каждому потомку. Это может быть просто логическое значение для каждого дочернего элемента, защищенного мьютексом. Дочерний объект периодически проверяет это значение (каждую итерацию цикла или любые удобные контрольные точки, которые есть у вас в дочернем потоке). Увидев, что «quit_request» имеет значение true, дочерний поток очищается и вызывает pthread_exit.

На родительской стороне подпрограмма kill_child выглядит примерно так:

acquire shared mutex
set quit_request to true 
pthread_join the child 

pthread_join может занять некоторое время, в зависимости от того, как часто ребенок проверяет свой запрос на выход. Убедитесь, что ваш дизайн может справиться с любой задержкой.

21 голосов
/ 29 сентября 2010

Можно "отменить" тему, используя pthread_cancel.Тем не менее, это, как правило, не лучшая практика, хотя в экстремальных условиях, таких как SEGFAULT, это может быть разумным подходом

7 голосов
/ 29 сентября 2010

Вы должны отправить SIG_TERM в каждый из ваших потоков, используя

  int pthread_kill(pthread_t thread, int sig);

. Быстрый способ избавиться от всех потоков (кроме основного) - это fork () и продолжить работу с потомком.Не сверхчистый ...

  if (fork()) exit(0); // deals also with -1...
3 голосов
/ 08 января 2011

Вы можете использовать глобальную переменную для всей программы.

int _fCloseThreads;

Установите значение 1, когда хотите, чтобы потоки прекратили выполнение. Пусть потоки проверят эту переменную в своем «цикле» и красиво выйдут, когда она установлена ​​в 1. Нет необходимости защищать ее мьютексом.

Вам нужно дождаться завершения потоков. Вы можете использовать соединение. Другой способ заключается в увеличении счетчика, когда поток входит в свой поток, и затем декрицификации счетчика при выходе. Счетчик должен быть своего рода глобальным. Используйте gcc Atomic Ops на счетчике. Основной поток после установки fCloseThreads может ожидать на счетчике обнуления, зацикливаясь, спя и проверяя счетчик.

Наконец, вы можете проверить pthread_cleanup_push и pop. Они представляют собой модель, позволяющую потоку отменять любое место в своем коде (использует longjump) и затем вызывать функцию окончательной очистки перед выходом из threadproc. По сути, вы помещаете cleanup_push вверху вашего threadproc и cleanup_pop внизу, создаете функцию размотки, а затем в определенных точках отмены поток, отмененный вызовом pthread_cancel (), будет долго возвращаться к threadproc и вызывать функцию unwind.

...