我有一个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强制转换为struct pthread *
来窃取线程ID。我想,更好的是,因为依赖私有实现甚至要求更多麻烦。
我也一直在阅读pthread_getunique_np函数,但这会返回一个“唯一的整数标识符” - 我认为它不会以任何形式或形式等同于OS线程ID。
因此,问题是:如何从任意pthread_t获取线程ID?
答案 0 :(得分:33)
由于pthread
不需要用Linux线程(或根本就是内核线程)实现,并且某些实现完全是用户级或混合的,pthread
的接口没有提供访问这些实现细节的函数,因为那些不可移植(甚至在Linux上的pthread
实现中)。使用它们的线程库可以将它作为扩展,但似乎没有这样做。
除了访问线程库的内部数据结构(你可以理解的是不想要,虽然你对处理器关联性和Linux线程ID的假设,你的代码无论如何都不可移植),你可能会玩一个技巧在创建时,如果您控制创建线程的代码:
给pthread_create()
一个调用gettid()
的条目函数(这可能是您可能需要直接使用syscall
宏的方式,因为它并不总是由{{1}导出}},将结果存储在某处,然后调用原始的入口函数。如果您有多个具有相同条目函数的线程,则可以将递增的指针传递到libc
参数中的数组arg
,然后将其传递给您创建的用于存储线程的条目函数ID in。以相同的顺序存储pthread_create
pthread_t
的返回值,然后您将能够查找您创建的pthread_create
值所有线程的Linux线程ID。
这个技巧是否值得,取决于设置CPU亲和性的重要性,而不是访问线程库的内部结构或取决于提供pthread_t
的线程库。
答案 1 :(得分:12)
实际上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;
}
答案 2 :(得分:1)
我建议使用共享的int数组进行简单的解决方法,您可以从线程中编写线程ID以便以后访问它。
希望有所帮助。
答案 3 :(得分:1)
pthread_t pthread_self()
这个返回当前的pthread_t,它是线程id,你可以将它转换为“unsigned int”类型,
答案 4 :(得分:1)
在 glibc 2.24 中,返回的pthread_t
只是指向不透明struct pthread
的指针。您可以在nptl/descr.h
中查找定义。