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() { remove_thread(pthread_self()); } unsigned thread_id(pthread_t known_pthread_id) { return seatch_thread_index(known_pthread_id); } 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.