为什么多个线程加入一个线程是undefined?

Why is it undefined if multiple threads join a thread?

如果我有多个线程并且我想等待一个线程完成,为什么根据 pthread_join() 函数未定义?

例如,下面的代码显示线程 1 和 2 等待线程 0:

void* thread1(void* t1){
..
pthread_join(pthread_t thread0, void **retval1);
return NULL
}

void* thread2(void* t2){
..
pthread_join(pthread_t thread0, void **retval2);
return NULL
}

为什么这种行为是未定义的或换句话说不可能的?

基本上,thread0retval 一直存储到 一个 线程调用 pthread_join。之后,retval 不再可用。

C++ 有 std::shared_future 明确设计为多个线程可以等待单个结果,这表明您的想法并不奇怪。

pthread_t 对象通常指向与线程相关的一些已分配数据。在这些数据中,通常是线程的 return 值。 pthread_join 将读取 return 值并释放线程数据。

如果您 pthread_join 相同的 pthread id 两次,您可能会遇到 double-free 的情况。指向的数据在第二次连接时可能无效,但它也可能已被另一个线程以不可预测的方式重用。

结果 difficult/impossible 值得推敲。因此,UB。

pthread_join 是一种资源标识符释放操作,例如文件描述符上的 close、分配的内存上的 free、文件名上的 unlink 等等。所有这些如果将来可以再次使用标识符(这里是构成 pthread_t 值的特定位模式),操作本质上会受到 "double-free"/"use-after-free" 错误的影响。因此,该行为要么完全未定义,要么受制于使其成为严重编程错误的条件,以至于它也可能未定义。

请注意,在您的心智模型中,您可能会想到 pthread_join 调用 "starting before the thread exits",因此发生在 pthread_t 标识符仍然有效的时间内。无论形式如何,它们之间没有顺序,也不可能有。 "already blocked in pthread_join" 和 "just about to call pthread_join" 的状态之间没有明显的区别。