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

时间:2009-02-17 19:57:43

标签: c linux unix pthreads system-calls

我有一个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?

5 个答案:

答案 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中查找定义。