Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get a thread ID from an arbitrary pthread_t?

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?

like image 928
Skrud Avatar asked Feb 17 '09 19:02

Skrud


People also ask

How do I get thread ID?

The pthread_self() function is used to get the ID of the current thread. This function can uniquely identify the existing threads. But if there are multiple threads, and one thread is completed, then that id can be reused. So for all running threads, the ids are unique.

What is a thread ID?

Thread Id is a long positive integer that is created when the thread was created. During the entire lifecycle of a thread, the thread ID is unique and remains unchanged. It can be reused when the thread is terminated.

What is pthread_t TID?

In main() we declare a variable called thread_id , which is of type pthread_t . This is basically an integer used to identify the thread in the system. After declaring thread_id , we call the pthread_create function to create a real, living thread.

Do threads have IDs?

The getId() method of Thread class returns the identifier of the invoked thread. The thread ID is a positive long number generated when this thread was created. The thread ID is unique and remains unchanged during its lifetime.


2 Answers

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.

like image 114
Tom Alsberg Avatar answered Sep 20 '22 16:09

Tom Alsberg


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; } 
like image 27
jayadev Avatar answered Sep 18 '22 16:09

jayadev