How can you get the Linux thread Id of a std::thread()
Solution 1
Assuming you're using GCC standard library, std::thread::native_handle()
returns the pthread_t
thread ID returned by pthread_self()
, not the OS thread ID returned by gettid()
. std::thread::id()
is a wrapper around that same pthread_t
, and GCC's std::thread
doesn't provide any way to get the OS thread ID, but you could create your own mapping:
std::mutex m;
std::map<std::thread::id, pid_t> threads;
void add_tid_mapping()
{
std::lock_guard<std::mutex> l(m);
threads[std::this_thread::get_id()] = syscall(SYS_gettid);
}
void wrap(void (*f)())
{
add_tid_mapping();
f();
}
Then create your thread with:
std::thread t1(&wrap, &SayHello);
then get the ID with something like:
pid_t tid = 0;
while (tid == 0)
{
std::lock_guard<std::mutex> l(m);
if (threads.count(t1.get_id()))
tid = threads[t1.get_id()];
}
Solution 2
Some pthread implementations, e.g. Android 21+, provide
pid_t pthread_gettid_np(pthread_t);
The implementation may use the internal structure of struct pthread_t
to retrieve the native thread id, same as the one returned by gettid()
or syscall(SYS_gettid)
when called in the context of that thread.
Char Aznable
Updated on June 05, 2022Comments
-
Char Aznable almost 2 years
I was playing with
std::thread
and I was wondering how is it possible to get the thread id of a newstd::thread()
, I am not talking aboutstd::thread::id
but rather the OS Id given to the thread ( you can view it usingpstree
). This is only for my knowledge, and it's targeted only to Linux platforms (no need to be portable).I can get the Linux Thread Id within the thread like this :
#include <iostream> #include <thread> #include <unistd.h> #include <sys/syscall.h> #include <sys/types.h> void SayHello() { std::cout << "Hello ! my id is " << (long int)syscall(SYS_gettid) << std::endl; } int main (int argc, char *argv[]) { std::thread t1(&SayHello); t1.join(); return 0; }
But how can I retrieve the same id within the main loop ? I did not find a way using
std::thread::native_handle
. I believed it was possible to get it troughpid_t gettid(void);
since the c++11 implementation relies on pthreads, but i must be wrong.Any advices ? Thank you.
-
Char Aznable about 11 yearsI think this is useful if you have a wrapper around
std:thread
orpthreads
, but I can't call it from outside the thread. (correct me if I'm wrong). Thanks. -
Char Aznable almost 11 yearsOh getting the id this way is smart, that's great , thanks you !
-
the swine almost 10 yearsWhy would you build a std::map? Is the
syscall()
expected to be so expensive? Also, you never seem to remove threads from the map, which could be viewed as a memory leak (e.g. in a webserver setting where many threads are spawned over time and the process typically runs for months without restarting). -
Jonathan Wakely almost 10 years@theswine, the syscall gives you the ID of the current thread, the map lets you find the ID of any thread, given its
thread::id
. That's more flexible. It's not strictly a leak, since the memory is still reachable, but to keep the memory usage bounded (and to cope with thread IDs being reused) you could use athread_local
object that adds to the map in its constructor and removes from the map in its destructor. The answer was a sketch demonstrating a solution, if you want something more robust then make it more robust. -
the swine almost 10 years@JonathanWakely You are right, I did not realize that you might want to get thread id outside of the thread. Thanks for the explanation.
-
rph almost 6 yearsI just wanted to emphasize that the
while(tid ==0)
is very important because the parent thread might reach the get thread id statement earlier than the mapping happens.