我有一个pthread_t,我想改变它的CPU亲和力.问题是我使用的是glibc 2.3.2,它没有pthread_setaffinity_np().但这没关系,因为pthread_setaffinity_np()本身就是sched_setaffinity()的包装器,可以通过传递线程ID而不是进程ID来调用,以设置任意线程的关联.
但是 ...... sched_setaffinity可以使用的线程ID是一个操作系统线程ID,可以从gettid()系统调用获得.这与opaque类型pthread_t不同,gettid()只返回当前线程的thread-id .我需要能够设置任意线程的CPU亲和性.
不幸的是,我无法访问pthread的私有部分,这会让我通过将pthread_t转换为a来窃取线程ID struct pthread *
.我想,更好的是,因为依赖私有实现需要更多麻烦.
我也一直在阅读pthread_getunique_np函数,但是这会返回一个"唯一的整数标识符" - 我认为它不会以任何形式或形式等同于OS线程ID.
因此,问题是:如何从任意pthread_t获取线程ID?
因为pthread
s不需要用Linux线程(或根本就是内核线程)实现,并且一些实现完全是用户级或混合的,所以pthread
s接口不提供访问这些实现细节的函数,因为那些不可移植(即使pthread
是Linux 上的实现).使用它们的线程库可以将其作为扩展提供,但似乎没有这样做.
除了访问线程库的内部数据结构(你可以理解的是,它不需要,尽管你对处理器关联性和Linux线程ID的假设,你的代码无论如何都不可移植),你可以在创建时玩一个技巧,如果您控制创建线程的代码:
给出pthread_create()
一个调用的入口函数gettid()
(顺便说一下你可能不得不syscall
直接使用宏,因为它不总是被导出libc
),将结果存储在某处,然后调用原始入口函数.如果你有相同的入口函数的多个线程,你可以传递一个递增的指针到一个数组arg
参数pthread_create
,然后将传递到您创建的存储线程ID的入口函数,存放pthread_t
的返回值pthread_create
在相同的顺序,然后您将能够查找您创建的所有线程的Linux线程ID给定它们的pthread_t
值.
这个技巧是否值得,取决于在您的情况下设置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; }