为什么 pthread_join 不接受线程指针?

Kru*_*own 6 c c++ linux pthreads

非常不言自明的问题。例如,pthread_create 的标头显示它需要一个指向线程的指针:

int WINPTHREAD_API pthread_create(pthread_t *th, const pthread_attr_t *attr, void *(* func)(void *), void *arg);
Run Code Online (Sandbox Code Playgroud)

好的,有道理,您在内存中分配一个 pthread,然后传递一个指向 pthread_create 的指针,以便它被初始化......但现在查看 pthread_join 的标头:

int WINPTHREAD_API pthread_join(pthread_t t, void **res);
Run Code Online (Sandbox Code Playgroud)

它需要 pthread_t 的副本。我只是不明白为什么它不使用指向已经存在的线程的指针,而不是复制它并传递它;似乎这样做会导致更多问题和更多内存使用。我错过了什么吗?我阅读了联机帮助页,它似乎没有提供这样做的原因。

Joh*_*ger 5

它需要一份pthread_t.

是的。

我只是不明白为什么它不使用指向已经存在的线程的指针,

pthread_t是一个线程标识符。规范始终如此引用它。复制它不会复制线程本身,也不会消耗比线程pthread_t占用更多的内存。

而不是复制并传递它;似乎这样做会导致更多问题和更多内存使用。

它不一定会导致更多的内存使用,因为 apthread_t不一定比指针大。它可能一个指针,也可能是一个整数。然而,即使它是一个结构,也没有理由认为它太大以至于按值传递它会带来严重问题,因为细节是在 pthreads 实现的控制之下的。为什么实施者会这样搬起石头砸自己的脚?请注意,按值传递结构本质上并不比传递指针效率低。

至于除了过度内存使用之外的问题,您必须更具体,但我没有看到直接访问线程标识符副本. 出于那些接受按值的函数的目的,间接访问公共标识符对象pthread_t

我错过了什么吗?

我怀疑您的担忧与类型的误解有关,pthread_t因为类型以某种方式携带支持线程操作的数据,而不是简单地识别线程。

您可能还假设 pthreads 是一个具有特定实现的库,而事实上,它首先是一个规范,旨在提供多种实现。pthread_t这是定义抽象数据类型而不是指定int或的部分原因struct something *——实现可以选择要使用的实际类型。

也许您也过于关注 API 函数。即使在某些特定的实现中,pthread_t按值传递 apthread_join()的效率比将指针传递给 a 的效率低,您认为这实际上会产生多大的影响? pthread_join()很少被调用,并且仅在调用者准备阻止的情况下被调用。如果参数传递比其他情况多消耗几纳秒,那又有什么关系呢?

我阅读了联机帮助页,它似乎没有提供这样做的原因。

很少有手册页提供功能设计的基本原理,但我认为最可能的解释本质上是形式服从功能。那些pthread_t按值接收的函数这样做是因为它们不需要或不想修改调用者的值。函数的设计反映了这一点。