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

发布于 2024-07-13 23:24:14 字数 991 浏览 8 评论 0 原文

我有一个 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 转换为 struct pthread * 来窃取线程 id。 我想这更好,因为依赖私有实现会带来更多的麻烦。

我还一直在阅读 pthread_getunique_np 函数,但是这会返回一个“唯一的整体标识符”——我不认为它以任何方式等同于操作系统线程 ID。

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

I have a pthread_t, and I'd like to change its CPU affinity. The problem is that I'm using glibc 2.3.2, which doesn't have pthread_setaffinity_np(). That's OK, though, because pthread_setaffinity_np() is itself a wrapper of sched_setaffinity(), which can be called by passing a thread ID instead of a process ID to set the affinity for an arbitrary thread.

BUT ... The thread id that sched_setaffinity can work with is an OS thread id, the kind that you can get from the gettid() system call. This is different from the opaque type pthread_t, and gettid() will only return the thread-id of the current thread. I need to be able to set the CPU affinity of an arbitrary thread.

Unfortunately, I can't access the pthread's private parts, which would let me steal the thread id by casting a pthread_t to a struct pthread *. All the better, I guess, since relying on private implementations is asking for even more trouble.

I've also been reading up on the pthread_getunique_np function, however this returns a "unique integral identifier" -- which I don't believe is in any way shape or form equivalent to an OS thread id.

Hence, the question: How can I get a thread ID from an arbitrary pthread_t?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

野侃 2024-07-20 23:24:15

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

希望有帮助。

I would suggest a simple workaround with a shared int array where you could write the thread id from the threads to access it later.

Hope that helps.

平安喜乐 2024-07-20 23:24:14

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

除了访问线程库的内部数据结构(可以理解,您不希望这样做,尽管根据您对处理器关联性和 Linux 线程 ID 的假设,您的代码无论如何都不可移植),您也许可以在创建时玩点小把戏,如果您控制创建线程的代码:

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

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

Since pthreads do not need to be implemented with Linux threads (or kernel threads at all, for that matter), and some implementations are entirely user-level or mixed, the pthreads interface does not provide functions to access these implementation details, as those would not be portable (even across pthreads implementations on Linux). Thread libraries that use those could provide this as an extension, but there do not seem to be any that do.

Other than accessing internal data structures of the threading library (which you understandably do not want, although with your assumptions about processor affinity and Linux thread IDs, your code will not be portable anyway), you may be able to play a trick at creation time, if you control the code that creates the threads:

Give pthread_create() an entry function that calls gettid() (which by the way you are likely to have to do using the syscall macro directly because it is not always exported by libc), stores the result somewhere, and then calls the original entry function. If you have multiple threads with the same entry function, you can pass an incremented pointer into an array in the arg argument to pthread_create, which will then be passed to the entry function you created to store the thread ID in. Store the pthread_t return value of pthread_create in the same order, and then you will be able to look up the Linux thread IDs of all threads you created given their pthread_t value.

Whether this trick is worth it, depends on how important setting the CPU affinity is in your case, versus not accessing internal structures of the thread library or depending on a thread library that provides pthread_setaffinity_np.

过度放纵 2024-07-20 23:24:14

实际上,pthread_self 返回 pthread_t 而不是您可以使用的整数线程 ID,以下辅助函数将以跨不同 POSIX 系统的可移植方式为您提供该 ID。

uint64_t gettid() {
    pthread_t ptid = pthread_self();
    uint64_t threadId = 0;
    memcpy(&threadId, &ptid, std::min(sizeof(threadId), sizeof(ptid)));
    return threadId;
}

Actually pthread_self returns pthread_t and not a integer thread id you can work with, the following helper function will get you that in a portable way across different POSIX systems.

uint64_t gettid() {
    pthread_t ptid = pthread_self();
    uint64_t threadId = 0;
    memcpy(&threadId, &ptid, std::min(sizeof(threadId), sizeof(ptid)));
    return threadId;
}
哀由 2024-07-20 23:24:14

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

In glibc 2.24 the pthread_t returned is just the pointer to an opaque struct pthread. You can look up the definition in nptl/descr.h.

给不了的爱 2024-07-20 23:24:14
pthread_t pthread_self()

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

pthread_t pthread_self()

this return current pthread_t, which is thread id, you can convert it to type "unsigned int",

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文