How to print pthread_t

Searched, but did not find a satisfactory answer.

I know that there is no portable way to print pthread_t.

How do you do this in your application?

Update:

Actually I don't need pthread_t, but some small numerical identifier identifying different threads in the debug message.

On my system (64-bit RHEL 5.3) it is defined as unsigned long int, so it has a large number and just prints that it eats valuable place in the debug line. How does gdb assign short teeds?

+48
c ++ c linux pthreads
Nov 18 '09 at 23:08
source share
12 answers

This will print out the hexadecimal representation of pthread_t , regardless of what it actually is:

 void fprintPt(FILE *f, pthread_t pt) { unsigned char *ptc = (unsigned char*)(void*)(&pt); fprintf(f, "0x"); for (size_t i=0; i<sizeof(pt); i++) { fprintf(f, "%02x", (unsigned)(ptc[i])); } } 

To just print a small identifier for each pthread_t , something like this could be used (this time using iostreams):

 void printPt(std::ostream &strm, pthread_t pt) { static int nextindex = 0; static std::map<pthread_t, int> ids; if (ids.find(pt) == ids.end()) { ids[pt] = nextindex++; } strm << ids[pt]; } 

Depending on the platform and the actual representation of pthread_t it may be necessary to define operator< for pthread_t , because std::map needs to be ordered by elements:

 bool operator<(const pthread_t &left, const pthread_t &right) { ... } 
+32
Nov 18 '09 at 23:23
source share
— -

GDB uses thread-id (aka kernel pid, aka LWP) for short numbers on Linux. Try:

  #include <syscall.h> ... printf("tid = %d\n", syscall(SYS_gettid)); 
+23
Nov 18. '09 at 23:39
source share

In this case, it depends on the operating system, since the POSIX standard no longer requires pthread_t be an arithmetic type :

IEEE Std 1003.1-2001 / Cor 2-2004 applies the XBD / TC2 / D6 / 26 element, adding pthread_t to the list of types that are not required for arithmetic types, which allows pthread_t be defined as a structure.

You will need to look in your sys/types.h header and see how pthread_t implemented; then you can print it as you see fit. Since there is no portable way to do this, and you are not saying which operating system you are using, there is nothing more to say.

Edit: To answer your new question, GDB assigns its own stream identifiers each time a new stream starts :

For debugging purposes, gdb associates its thread number — always one piece — with each thread in your program.

If you want to print a unique number inside each thread, the easiest option is probably to tell each thread which number to use when it starts.

+15
Nov 18 '09 at 23:13
source share

OK, this seems to be my final answer. We have two actual problems:

  • How to get shorter unique identifiers for a log stream.
  • In any case, we need to print the real identifier pthread_t for the thread (at least to refer to POSIX values).

1. Print POSIX ID (pthread_t)

You can simply treat pthread_t as an array of bytes with hexadecimal digits printed for each byte. Thus, you are not limited to any fixed type. The only problem is the byte order. You will probably enjoy it if the order of your printed bytes is the same as for a simple "int". Here is an example for little-endian and only the order should be returned (under define?) For big-endian:

 #include <pthread.h> #include <stdio.h> void print_thread_id(pthread_t id) { size_t i; for (i = sizeof(i); i; --i) printf("%02x", *(((unsigned char*) &id) + i - 1)); } int main() { pthread_t id = pthread_self(); printf("%08x\n", id); print_thread_id(id); return 0; } 

2. Get a shorter stream identifier for printing

In any of the proposed cases, you need to translate the real thread identifier (posix) into the index of some table. But there are 2 essentially different approaches:

2.1. Track topics.

You can track the thread IDs of all existing threads in the table (their pthread_create () calls must be wrapped) and have an "overloaded" id function that gives you only the table index and not the real thread ID. This scheme is also very useful for any internal thread debugging resource tracking. An obvious advantage is the side effect of the thread level tracer / debugger with possible expansion. The disadvantage is the requirement to track the creation / destruction of threads.

Here is an example of partial pseudocode:

 pthread_create_wrapper(...) { id = pthread_create(...) add_thread(id); } pthread_destruction_wrapper() { /* Main problem is it should be called. pthread_cleanup_*() calls are possible solution. */ remove_thread(pthread_self()); } unsigned thread_id(pthread_t known_pthread_id) { return seatch_thread_index(known_pthread_id); } /* user code */ printf("04x", thread_id(pthread_self())); 

2.2. Just register a new thread id.

While logging, call pthread_self () and find the internal table if it knows the thread. If a stream with such an identifier was created, its index is used (or reused from the previous stream, in fact, it does not matter, since at the same moment there are no two identical identifiers). If the stream identifier is not yet known, a new record is created, so a new index is created and used.

The advantage is simplicity. The disadvantage is the lack of tracking of thread creation / destruction. Therefore, tracking requires some kind of external mechanics.

+7
Nov 18 '09 at 23:35
source share

On Centos 5.4 x86_64, pthread_t is a typedef for unsigned long.

So we could do it ...

 #include <iostream> #include <pthread.h> int main() { pthread_t x; printf("%li\n", (unsigned long int) x); std::cout << (unsigned long int) x << "\n"; } 
+4
Nov 18 '09 at 23:15
source share

You can do something like this:

 int thread_counter = 0; pthread_mutex_t thread_counter_lock = PTHREAD_MUTEX_INITIALIZER; int new_thread_id() { int rv; pthread_mutex_lock(&thread_counter_lock); rv = ++thread_counter; pthread_mutex_unlock(&thread_counter_lock); return rv; } static void *threadproc(void *data) { int thread_id = new_thread_id(); printf("Thread %d reporting for duty!\n", thread_id); return NULL; } 

If you can rely on having GCC (clang also works in this case), you can also do this:

 int thread_counter = 0; static void *threadproc(void *data) { int thread_id = __sync_add_and_fetch(&thread_counter, 1); printf("Thread %d reporting for duty!\n", thread_id); return NULL; } 

If your platform supports this, a similar option:

 int thread_counter = 0; int __thread thread_id = 0; static void *threadproc(void *data) { thread_id = __sync_add_and_fetch(&thread_counter, 1); printf("Thread %d reporting for duty!\n", thread_id); return NULL; } 

This has the advantage that you do not need to pass thread_id to function calls, but it does not work, for example. on Mac OS.

+3
Nov 19 '09 at 0:17
source share

if pthread_t is just a number; that would be the easiest.

 int get_tid(pthread_t tid) { assert_fatal(sizeof(int) >= sizeof(pthread_t)); int * threadid = (int *) (void *) &tid; return *threadid; } 
+3
Aug 10 2018-12-12T00:
source share

The lookup table (pthread_t : int) can become a memory leak in programs that run many short-lived threads.

Creating a pthread_t byte hash (whether it's a structure or pointer or a long integer or something else) can be a useful solution that doesn't require lookup tables. As with any hash, there is a risk of collision, but you can customize the hash length to suit your requirements.

+2
Nov 30 '12 at 15:08
source share

You can try converting it to unsigned short and then print only the last four hexadecimal digits. The resulting value may be unique to your needs.

+1
Nov 18 '09 at 23:47
source share

I know this topic is very old. After reading all of the above entries, I would like to add another idea to handle this in a neat way: If you still get into the mapping company (matching pthread_to with int), you can also take another step in readability. Make your pthread_create_wrapper such that it also takes a string ... the name of the thread. I have learned to appreciate this "SetThreadName ()" function on windows and CE windows. Advantages: Your identifiers are not just numbers, but you also see which of your goals has a purpose.

+1
Apr 16 '13 at 9:29
source share

Just an appendix to the first post: use a user-defined join type to store pthread_t:

 union tid { pthread_t pthread_id; unsigned long converted_id; }; 

Whenever you want to print pthread_t , create tid and assign tid.pthread_id = ... , then print tid.converted_id .

0
Aug 28 '17 at 5:10
source share

As James mentioned, the best way is to look at the header in which the type is defined.

You can find the definition of pthread_t in pthreadtypes.h, which can be found at:

/usr/include/bits/pthreadtypes.h

0
Jul 10 '19 at 6:52
source share



All Articles