Ошибка сегментации, вызванная pthread_kill - PullRequest
8 голосов
/ 13 декабря 2011

GDB говорит мне, что pthread_kill вызывает ошибку сегментации в моей программе.В основном я использую pthread_kill, чтобы проверить, жив ли поток или нет его ID.

Я искал в Интернете и обнаружил, что, возможно, pthread_kill вызывает ошибку сегментации, когда TID недействителен.Да, я тестировал свою программу, используя «недействительные» (придуманные мной) TID типа int.Может ли это быть реальной причиной?

Ответы [ 2 ]

14 голосов
/ 13 декабря 2011

pthread_t не является идентификатором потока или числовым индексом.Это непрозрачный тип.Создание значений может привести к сбою.

В Linux NPTL в качестве указателя используется pthread_t:

int
__pthread_kill (threadid, signo)
     pthread_t threadid;
     int signo;
{
  struct pthread *pd = (struct pthread *) threadid;

Должно быть достаточно ясно, где что-то идет не так :) Обратите внимание, чтоэта особенность также является деталью реализации - более старая реализация Linuxthreads использовала числовые индексы в таблице, и там вы действительно могли бы составлять TID и не ожидать, что что-то рухнет.

Вы должны сами следить за жизнью и смертью потока,pthread_t действует до тех пор, пока вы успешно не наберете pthread_join.Если вы хотите проверить, активен ли valid pthread_t, позвоните по номеру pthread_tryjoin_np;если он возвращает EBUSY, поток жив.Если функция завершается успешно, pthread_t больше не действителен ;Вы не должны повторно использовать его на этом этапе - поэтому вы должны где-то отметить, что этот поток сейчас мертв, и нет необходимости проверять его больше!

Конечно, вы можете реализовать свое собственное отслеживаниеsystem - создать где-нибудь таблицу жизнедеятельности, систему для выдачи TID и передачи их во вновь созданные потоки.Сделайте так, чтобы каждый поток помечал себя как мертвый перед выходом (возможно, используя pthread_cleanup_push, чтобы вы обрабатывали отмену потока и pthread_exit), и отсоединяйте поток, чтобы вам не нужно было присоединяться к нему (используя pthread_detach).Теперь у вас есть явный контроль над сообщениями о потере потоков.

1 голос
/ 04 июня 2013

Чтобы обойти это ограничение в моем коде, я устанавливаю TID в ноль, когда код не выполняется

memset(&thread, '\0', sizeof(pthread_t)); 

... и проверяю его на ноль перед вызовом pthread_kill

//this code will run if thread is not valid
if (!thread || ESRCH == pthread_kill(thread, 0)) {
    //do stuff and create the thread
}
...