44

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

但是...... sched_setaffinity 可以使用的线程 id 是操作系统线程 id,您可以从gettid()系统调用中获得这种类型。这与不透明类型 pthread_t 不同,gettid() 只会返回当前线程的线程 ID 。我需要能够设置任意线程的 CPU 亲和性。

不幸的是,我无法访问 pthread 的私有部分,这会让我通过将 pthread_t 强制转换为 a 来窃取线程 ID struct pthread *。我猜这样会更好,因为依赖私有实现会带来更多麻烦。

我也一直在阅读pthread_getunique_np函数,但是这会返回一个“唯一的整数标识符”——我不相信它在任何形状或形式上都等同于操作系统线程 ID。

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

4

5 回答 5

37

由于pthreads 不需要使用 Linux 线程(或内核线程,就此而言)实现,并且某些实现完全是用户级的或混合的,因此pthreads 接口不提供访问这些实现细节的函数,因为那些不可移植(即使跨pthreadLinux 上的 s 实现)。使用这些的线程库可以将其作为扩展提供,但似乎没有任何这样做。

除了访问线程库的内部数据结构(这是可以理解的,尽管您对处理器亲和性和 Linux 线程 ID 的假设,您的代码无论如何都不会是可移植的),您也许可以在创建时玩一个技巧,如果您控制创建线程的代码:

给出pthread_create()一个调用的入口函数gettid()(顺便说一下,您可能不得不syscall直接使用宏,因为它并不总是由 导出libc),将结果存储在某处,然后调用原始入口函数。arg如果您有多个线程具有相同的入口函数,则可以将递增的指针传递到参数中的数组中pthread_create,然后将其传递给您创建的入口函数以存储线程 ID。将 的pthread_t返回值存储pthread_create在相同的顺序,然后您将能够在给定pthread_t值的情况下查找您创建的所有线程的 Linux 线程 ID 。

这个技巧是否值得,取决于在您的情况下设置 CPU 亲和性的重要性,而不是不访问线程库的内部结构或取决于提供pthread_setaffinity_np.

于 2009-02-17T21:29:49.683 回答
13

实际上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;
}
于 2013-09-10T02:06:49.247 回答
2
pthread_t pthread_self()

这返回当前的 pthread_t,即线程 id,你可以将其转换为类型“unsigned int”,

于 2013-09-06T10:40:08.807 回答
2

glibc 2.24中,pthread_t返回的只是指向 opaque 的指针struct pthread。您可以在 中查找定义nptl/descr.h

于 2017-09-21T11:56:04.667 回答
1

我建议使用共享 int 数组的简单解决方法,您可以在其中从线程中写入线程 id 以便稍后访问它。

希望有帮助。

于 2009-02-17T21:23:13.083 回答