为什么 pthread_join 不会阻塞并等待线程完成?

时间:2021-02-01 06:46:41

标签: c multithreading operating-system pthreads

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

void* thread(void *v) {
    printf("The thread starts now\n");
    //pthread_exit(NULL);
}

int main() {
    int tid1;
    int retValue = 0;
    pthread_create(&tid1, NULL,thread, NULL);

    retValue = pthread_join(tid1, NULL);
    printf("Thread ID: %d, return value: %d\n",tid1, retValue);

    retValue = pthread_join(tid1, NULL);
    printf("Thread ID: %d, return value: %d\n",tid1, retValue);
    return 0;
}

有时输出是:

Thread ID: 1877241856, return value: 3
Thread ID: 1877241856, return value: 3
The thread starts now

Process finished with exit code 0

问题是:

  1. 根据定义,pthread_join 应该阻塞,等待 thread 执行完毕,然后执行它后面的代码。但是为什么在我的代码中,thread 在两个 pthread_join 完成后运行?

  2. 根据定义,pthread_join 返回 0 表示加入成功,但为什么我的代码的 retValue 始终为 3,无论 thread 在 {{1} 之前或之后运行}} 函数?

2 个答案:

答案 0 :(得分:4)

这段代码有很多错误:

  1. pthread_create() 的第一个参数应该是 pthread_t,而不是 int。它们的大小很可能不同,或者可以互换,因此 tid1 可能不是有效的 pthread id。

  2. 线程不返回 0 或任何其他与此相关的值。没有 return 语句。

  3. “成功时,pthread_join() 返回 0;错误时,它返回一个错误号。” 线程的返回值(如果有)将放入 pthread_join() 未使用的第二个参数中。被视为返回值的实际上是 pthread_join() 调用本身的结果。这是一个错误。也许它与上面的#1有关?

答案 1 :(得分:2)

除了那些被 TrentP 发现的最糟糕的 bug 是

<块引用>

加入一个先前已加入的线程会导致未定义的行为。

即在同一个线程上调用 pthread_join 两次

retValue = pthread_join(tid1, NULL);
retValue = pthread_join(tid1, NULL);

完全错误,如果您将 tid1 更改为 pthread_t 则说它有效是错误的。行为未定义意味着当第二次调用 pthread_join 时任何事情都可能发生 - pthread_join 可以返回错误,pthread_join 可以返回成功,它可以崩溃,它可以挂起,它可以修改内存的其他部分,可能会导致新线程启动...

相关问题