如何从任意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()
的入口函数(通过直接使用syscall
macros可能需要的方法,因为它并不总是由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
查找定义。