Вызовите присоединение дочернего pthread в основной функции

У меня есть тестовый код:

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

pthread_t th_worker, th_worker2;void * worker2(void *data) {
for(int i = 0; i< 1000000; i++){
printf("thread for worker2----%d\n", i);
usleep(500);
}
}
void * worker(void *data){
pthread_create(&th_worker2, NULL, worker2, data);

for(int i = 0; i< 100; i++){
printf("thread for worker-----%d\n", i);
usleep(500);
}
}
void join(pthread_t _th){
pthread_join(_th, NULL);
}

В функции main (), если я вызову join (the_worker2):

int main() {
char* str = "hello thread";

pthread_create(&th_worker, NULL, worker, (void*) str);
/* problem in here */
join(th_worker2);

return 1;
}

—> Ошибка сегмента

Еще я звоню:

join(the_worker);
join(th_worker2);

—> ОК

Почему ошибка сегмента в вышеуказанном случае?
Спасибо за помощь !!!

2

Решение

Если вы отправили все ваш код, у вас есть состояние гонки.

main синхронизируется с началом worker но не worker2,

То есть, main пытается присоединиться th_worker2 до worker был шанс призвать pthread_create и настроить th_worker2 с действительный [ненулевое] значение.

Так, th_worker2 будет недействительным до второго pthread_create завершает, но это уже слишком поздно для main, Он уже принес th_worker2, который имеет значение NULL и main будет сегфо

Когда вы добавляете соединение для th_worker, это работает, потому что это гарантии синхронизация и нет состояние гонки.


Чтобы достичь этой гарантии без объединения, сделайте так:

int
main()
{
char *str = "hello thread";

pthread_create(&th_worker, NULL, worker, (void *) str);

// give worker enough time to properly start worker2
while (! th_worker2)
usleep(100);

/* problem in here */
join(th_worker2);

return 1;
}

Еще лучший способ сделать это — добавить дополнительную переменную. При этом первый цикл не нужен [но я его оставил]:

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

int worker_running;
pthread_t th_worker;

int worker2_running;
pthread_t th_worker2;

void *
worker2(void *data)
{

// tell main we're fully functional
worker2_running = 1;

for (int i = 0; i < 1000000; i++) {
printf("thread for worker2----%d\n", i);
usleep(500);
}

return NULL;
}

void *
worker(void *data)
{

// tell main we're fully functional
worker_running = 1;

pthread_create(&th_worker2, NULL, worker2, data);

for (int i = 0; i < 100; i++) {
printf("thread for worker-----%d\n", i);
usleep(500);
}

return NULL;
}

void
join(pthread_t _th)
{
pthread_join(_th, NULL);
}

int
main()
{
char *str = "hello thread";

pthread_create(&th_worker, NULL, worker, (void *) str);

// give worker enough time to properly start worker2
// NOTE: this not necessarily needed as loop below is better
while (! th_worker2)
usleep(100);

// give worker2 enough time to completely start
while (! worker2_running)
usleep(100);

/* problem in here (not anymore!) */
join(th_worker2);

return 1;
}
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]