Ошибка сегментации после вызова pthread_join () - PullRequest
6 голосов
/ 03 мая 2011

Я написал следующий код с использованием библиотеки pthread POSIX:

#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>

pthread_t pid1,pid2;

void *test(void *arg)
{
void **end;
printf("\nNew Thread ID: 0x%x\n",(unsigned int)pid2);
pthread_join(pid1,end);
printf("\nNew Thread going to go off\n");
printf("\nNew Thread ID: 0x%x\n",(unsigned int)pid2);
return ((void *)NULL);
}    

int main()
{
pid1 = pthread_self();
pthread_create(&pid2,NULL,test,NULL);
printf("\nMain Thread ID: 0x%x\n",(unsigned int)pid1);
sleep(2);
printf("\nI am going off\n");
pthread_exit(0);
}

При выполнении кода я получил следующий вывод:

Main Thread ID: 0xb7880b30
New Thread ID: 0xb787eb70
I am going off
Segmentation fault

Как я изучал, поток (pid2) вызов pthread_join будет блокироваться до тех пор, пока поток, переданный в аргументе (pid1), не вызовет pthread_exit ().И pthread_exit () используется, чтобы остановить выполнение определенного потока, позволяя всем другим продолжать выполнение.

Я хочу знать, почему я наконец-то получил ошибку сегментации.

Пожалуйста, объясните мне правильно.

Ответы [ 4 ]

9 голосов
/ 04 мая 2011

Вы используете неинициализированную переменную void **end;, что приводит к неопределенному поведению:

pthread_join(pid1,end);

Вместо этого вам следует:

void *end;
pthread_join(pid1, &end);

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

5 голосов
/ 04 мая 2011

Я думаю, что проблема в том, что ваш end указатель, переданный pthread_join(), фактически нигде не указывает.Попробуйте следующее:

void *test(void *arg)
{
    void *end;    // <===
    printf("\nNew Thread ID: 0x%x\n",(unsigned int)pid2);
    pthread_join(pid1,&end);  // <===
    printf("\nNew Thread going to go off\n");
    printf("\nNew Thread ID: 0x%x\n",(unsigned int)pid2);
    return ((void *)NULL);
}
1 голос
/ 03 мая 2011

Ошибка сегментации просто означает, что вы пытались получить доступ к памяти или перейти в какое-то место в памяти, из-за которого ОС не позволяла вам ни выполнять код, ни читать / записывать из него.В этом случае, где ваш порожденный дочерний поток должен вернуться после вызова pthread_join(), поскольку ОС очистила основной родительский процесс и освободила всю память, используемую основным родительским процессом (включая код выполнения, а также стек-пространство, куча-пространство и т. д.)?... Это определенно не память, к которой имеет доступ пользовательский поток, поэтому ОС выдает ошибку сегментации.

0 голосов
/ 03 мая 2011

Вы вызываете pthread_exit () в главном потоке, который затем сразу же завершает работу, приходя в конец main (), завершая процесс. Второй поток разблокируется и оказывается в очень странном положении! На данный момент вы глубоко в земле неопределенного поведения. Вы должны вызвать pthread_join из основного потока.

...