How to print pthread_t

C++CLinuxPthreads

C++ Problem Overview


Searched, but don't come across a satisfying answer.

I know there's no a portable way to print a pthread_t.

How do you do it in your app?

Update:

Actually I don't need pthread_t, but some small numeric id, identifying in debug message different threads.

On my system (64 bit RHEL 5.3) it's defined as unsigned long int, so it's big number and just printing it eats a valuable place in debug line. How does gdb assign short tids?

C++ Solutions


Solution 1 - C++

This will print out a hexadecimal representation of a pthread_t, no matter what that 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 id for a 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 might here be necessary to define an operator< for pthread_t, because std::map needs an ordering on the elements:

bool operator<(const pthread_t &left, const pthread_t &right) {
  ...
}

Solution 2 - C++

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

  #include <syscall.h>
  ...

    printf("tid = %d\n", syscall(SYS_gettid));

Solution 3 - C++

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

> IEEE Std 1003.1-2001/Cor 2-2004, item XBD/TC2/D6/26 is applied, adding pthread_t to the list of types that are not required to be arithmetic types, thus allowing pthread_t to be defined as a structure.

You will need to look in your sys/types.h header and see how pthread_t is implemented; then you can print it how you see fit. Since there isn't a portable way to do this and you don't say what operating system you are using, there's not a whole lot more to say.

Edit: to answer your new question, GDB assigns its own thread ids each time a new thread starts:

> For debugging purposes, gdb associates its own thread number—always a single integer—with each thread in your program.

If you are looking at printing a unique number inside of each thread, your cleanest option would probably be to tell each thread what number to use when you start it.

Solution 4 - C++

OK, seems this is my final answer. We have 2 actual problems:

  • How to get shorter unique IDs for thread for logging.
  • Anyway we need to print real pthread_t ID for thread (just to link to POSIX values at least).

1. Print POSIX ID (pthread_t)

You can simply treat pthread_t as array of bytes with hex digits printed for each byte. So you aren't limited by some fixed size type. The only issue is byte order. You probably like if order of your printed bytes is the same as for simple "int" printed. Here is example for little-endian and only order should be reverted (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 shorter printable thread ID

In any of proposed cases you should translate real thread ID (posix) to index of some table. But there is 2 significantly different approaches:

2.1. Track threads.

You may track threads ID of all the existing threads in table (their pthread_create() calls should be wrapped) and have "overloaded" id function that get you just table index, not real thread ID. This scheme is also very useful for any internal thread-related debug an resources tracking. Obvious advantage is side effect of thread-level trace / debug facility with future extension possible. Disadvantage is requirement to track any thread creation / destruction.

Here is partial pseudocode example:

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 new thread ID.

During logging call pthread_self() and search internal table if it know thread. If thread with such ID was created its index is used (or re-used from previously thread, actually it doesn't matter as there are no 2 same IDs for the same moment). If thread ID is not known yet, new entry is created so new index is generated / used.

Advantage is simplicity. Disadvantage is no tracking of thread creation / destruction. So to track this some external mechanics is required.

Solution 5 - C++

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

Therefore, we could do this...

#include <iostream>
#include <pthread.h>

int main() {
    pthread_t x;
    printf("%li\n", (unsigned long int) x);
    std::cout << (unsigned long int) x << "\n";
}

Solution 6 - C++

You could 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 don't have to pass around thread_id in function calls, but it doesn't work e.g. on Mac OS.

Solution 7 - C++

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

int get_tid(pthread_t tid)
{
    assert_fatal(sizeof(int) >= sizeof(pthread_t));

    int * threadid = (int *) (void *) &tid;
    return *threadid;
}

Solution 8 - C++

A lookup table (pthread_t : int) could become a memory leak in programs that start a lot of short-lived threads.

Creating a hash of the bytes of the pthread_t (whether it be structure or pointer or long integer or whatever) may be a usable solution that doesn't require lookup tables. As with any hash there is a risk of collisions, but you could tune the length of the hash to suit your requirements.

Solution 9 - C++

I know, this thread is very old. Having read all above posts, I would like to add one more idea to handle this in a neat way: If you get into the mapping business anyway (mapping pthread_to to an int), you could as well go one step further in readability. Make your pthread_create_wrapper such that it takes a string, too...the name of the thread. I learned to appreciate this "SetThreadName()" feature on windows and windows CE. Advantages: Your ids are not just numbers but you also see, which of your threads has which purpose.

Solution 10 - C++

You could try converting it to an unsigned short and then print just the last four hex digits. The resulting value might be unique enough for your needs.

Solution 11 - C++

No need to get fancy, you can treat pthread_t as a pointer without a cast:

printf("awesome worker thread id %p\n", awesome_worker_thread_id);

Output:

> awesome worker thread id 0x6000485e0

Solution 12 - C++

Just a supplement to the first post: use a user defined union type to store the pthread_t:

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

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

Solution 13 - C++

As James mentioned above, the best way is to look at the header where 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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiondimbaView Question on Stackoverflow
Solution 1 - C++sthView Answer on Stackoverflow
Solution 2 - C++Employed RussianView Answer on Stackoverflow
Solution 3 - C++James McNellisView Answer on Stackoverflow
Solution 4 - C++Roman NikitchenkoView Answer on Stackoverflow
Solution 5 - C++Bill LynchView Answer on Stackoverflow
Solution 6 - C++LnxPrgr3View Answer on Stackoverflow
Solution 7 - C++sgowdView Answer on Stackoverflow
Solution 8 - C++JimView Answer on Stackoverflow
Solution 9 - C++user2173833View Answer on Stackoverflow
Solution 10 - C++David R TribbleView Answer on Stackoverflow
Solution 11 - C++Rich HoveyView Answer on Stackoverflow
Solution 12 - C++Harold H.View Answer on Stackoverflow
Solution 13 - C++ymdattaView Answer on Stackoverflow