Multithreading 为什么可以';在同一个线程上不进行多个pthread_连接?

Multithreading 为什么可以';在同一个线程上不进行多个pthread_连接?,multithreading,pthreads,posix,pthread-join,Multithreading,Pthreads,Posix,Pthread Join,发件人: 连接线程可以匹配一个pthread_join()调用。在同一线程上尝试多个联接是一个逻辑错误 同样来自“manpthread_join”: 如果多个线程同时尝试与同一线程联接,则结果未定义 然而,从程序员的角度来看,多个线程可能希望等待一个线程完成(类似于屏障),这是非常合理的 例如,我们可能让thread1和thread2独立运行,并且我们可能希望两个线程都等待thread3完成 这一限制背后有什么技术原因吗?Posix pthreads和Windows内核对象之间有着巨大的差异(我

发件人:

连接线程可以匹配一个pthread_join()调用。在同一线程上尝试多个联接是一个逻辑错误

同样来自“manpthread_join”:

如果多个线程同时尝试与同一线程联接,则结果未定义

然而,从程序员的角度来看,多个线程可能希望等待一个线程完成(类似于屏障),这是非常合理的

例如,我们可能让thread1和thread2独立运行,并且我们可能希望两个线程都等待thread3完成


这一限制背后有什么技术原因吗?

Posix pthreads和Windows内核对象之间有着巨大的差异(我显然认为您很熟悉)。我发现它有令人不快的局限性,而你只提到了一个。除了当前的实现细节之外,并没有真正的技术原因(是的,线程状态在加入后不会保存在内存中,但为什么?)。另一个非常令人不快的限制是缺乏在一次调用中连接多个线程的可能性,这可能是线程上的多路复用


尽管如此,每天仍有数以百万计的基于pthread的程序在运行,因此这些限制并不是一个障碍。但事实上,如果没有这些,某些任务将更容易执行。

我认为技术原因是pthread_join是一个POSIX标准,对于多线程,它试图为实现者指定只需要的原语。任何更丰富的语义都会引入更昂贵的实现,可能还会引入更困难的API

实际上,POSIX已经将此函数视为一种便利,而不是一种原语,以支持一个非常非常常见的用例:一个线程等待另一个线程的终止

POSIX.1-2008的第一段有点长,但提出了许多密切相关的意见:

pthread_join()函数非常方便,在多线程应用程序中非常有用。的确,如果没有通过将额外状态作为参数的一部分传递给start_例程()来提供此函数,程序员可以模拟此函数。终止线程将设置一个标志来指示终止,并广播作为该状态一部分的条件;连接线程将等待该条件变量。虽然这种技术允许线程在更复杂的条件下等待(例如,等待多个线程终止),但等待单个线程终止被认为是非常有用的。此外,包含pthread_join()函数并不妨碍程序员编写这种复杂的等待。因此,虽然不是原语,但在POSIX.1-2008的本卷中包含pthread_join()被认为是有价值的


pthread\u join()
返回后,将释放与退出线程关联的最后一个资源。没有其他
pthread\u join()
可以接触到该线程,因为它什么也没有留下。必须这样,否则pthread库怎么知道何时释放这些资源?如果多个线程可以用一个pthread连接,那么每个退出的线程都会有一个永久性的资源泄漏。那么,终止线程的资源(返回值)将保留在内存中,直到第一个线程实际连接并声明它为止?就像先到先得一样?不完全一样。这是“先到先得,如果有人后来来,那就要付出惨重的代价”。我可以说原因是什么,但他们可能会做一些令人不愉快的工作,比如pthread_detach,可能会找到一些析构函数或释放的锁进行选择。就像不是所有语言都有自动垃圾收集一样,并非所有线程库都可以跟踪谁可能仍然拥有已退出线程的句柄。您还可以问两次为什么不允许
free()
分配。@EOF,不。您不需要问“谁还有句柄”。您只是在连接时没有松开手柄。就是这样,简单明了。如果你的应用程序因为线程句柄使用了所有内存而内存不足,那么你的应用程序就有问题了。我不同意,反过来说:如果你的线程库不能永久地创建新线程,那么你的线程库就有问题了。我不喜欢windows编程,我非常喜欢linux和pthreads之类的东西,但我必须同意这种说法。这些是pthread中令人沮丧的限制。更糟糕的是,我看到很多人为高级语言包装pthreads,并且由于pthreads在这方面的灵感或不足而导出此限制,而不是出于必要性(即,线程优雅地关闭,这样它们就可以将状态更改弹出到一个带有互斥对象的队列,并将其发送到管理线程).感谢文件中的具体提及。了解到pthread_join是为了方便(因为可以使用其他技术实现更复杂的等待)。