在主函数中调用join子函数pthread

Call join child pthread in main function

本文关键字:join 子函数 pthread 调用 函数      更新时间:2023-10-16

我有测试代码:

#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----%dn", 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-----%dn", 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);

--->OK

为什么在上述情况下会出现分段故障错误?谢谢你的帮助!!!

如果您发布了所有代码,则存在竞争条件

mainworker的开始同步,但worker2

也就是说,在worker有机会调用pthread_create并设置具有有效[非null]值的th_worker2之前,main正试图加入th_worker2

因此,在第二个pthread_create完成之前,th_worker2将是无效的,但对于main来说已经太晚了。它已经获取了具有NULL值的th_worker2,并且main将segfault。

当您为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----%dn", 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-----%dn", 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;
}