如何从任意pthread_t获取线程ID?

我有一个pthread_t,我想改变它的CPU亲和力。 问题是我使用glibc 2.3.2,它没有pthread_setaffinity_np() 。 没关系,因为pthread_setaffinity_np()本身就是sched_setaffinity()的一个包装,可以通过传递线程ID而不是进程ID来设置任意线程的关联。

但是 … sched_setaffinity可以使用的线程ID是一个操作系统线程ID,可以从gettid()系统调用中获得。 这与opaquetypes的pthread_t不同 ,gettid()只会返回当前线程的thread-id。 我需要能够设置任意线程的CPU亲和力。

不幸的是,我不能访问pthread的私有部分,这会让我通过将pthread_t转换为struct pthread *来窃取线程id。 我猜,更好一些,因为依赖私有实现需要更多的麻烦。

我也一直在阅读pthread_getunique_np函数,但是这会返回一个“唯一的整型标识符” – 我不认为它是以任何forms或forms等同于操作系统线程ID。

因此,问题:我如何从任意pthread_t获得线程ID?

由于pthread不需要用Linux线程(或者根本就不用内核线程)来实现,而且有些实现完全是用户级的或者是混合的,所以pthread的接口不提供访问这些实现细节的函数,如那些将不可移植(甚至跨Linux上的pthread的实现)。 线程库使用这些可以提供这个作为扩展,但似乎没有任何做。

除了访问线程库的内部数据结构(你可以理解,不需要,尽pipe你对处理器关联和Linux线程ID的假设,你的代码无论如何都是不可移植的),你也许可以在创build时玩弄,如果您控制创build线程的代码:

pthread_create()一个调用gettid() pthread_create()的入口函数(通过直接使用syscallmacros可能需要的方法,因为它并不总是由libc导出),将结果存储在某处,然后调用原始条目function。 如果有多个具有相同入口函数的线程,则可以将递增的指针传递给arg参数中的一个数组pthread_create ,然后将其传递到您创build的用于存储线程ID的入口函数。存储pthread_t返回值的pthread_create以相同的顺序,然后您将能够查找您创build的所有线程的pthread_t值的Linux线程ID。

这个技巧是否值得,取决于设置CPU亲缘关系的重要性,而不是访问线程库的内部结构,或者取决于提供pthread_setaffinity_np的线程库。

实际上pthread_self返回的是pthread_t而不是一个你可以使用的整数线程id,下面的帮助函数将以一种便携的方式在不同的POSIX系统上得到你的帮助。

 uint64_t gettid() { pthread_t ptid = pthread_self(); uint64_t threadId = 0; memcpy(&threadId, &ptid, std::min(sizeof(threadId), sizeof(ptid))); return threadId; } 
 pthread_t pthread_self() 

这个返回当前的pthread_t,也就是线程ID,你可以把它转换成“unsigned int”types,

我会build议一个简单的解决方法,用一个共享的int数组,在那里你可以从线程中写入线程ID来稍后访问它。

希望有所帮助。

glibc 2.24中 ,返回的pthread_t只是指向一个不透明的struct pthread的指针。 你可以在nptl/descr.h查找定义。