Get thread identifier C
I am trying to get the identifier of a thread, but it always returns some random numbers. What isn't good here ?
// C program to demonstrate working of pthread_self()
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void* calls(void* ptr)
{
// using pthread_self() get current thread id
printf("In function \nthread id = %d\n", pthread_self());
pthread_exit(NULL);
return NULL;
}
int main()
{
pthread_t thread; // declare thread
pthread_create(&thread, NULL, calls, NULL);
printf("In main \nthread id = %d\n", thread);
pthread_join(thread, NULL);
return 0;
}
Solution 1:
Maybe it would be good time to read the documentation. For Linux, it is said that
NOTES
POSIX.1 allows an implementation wide freedom in choosing the type used to represent a thread ID; for example, representation using either an arithmetic type or a structure is permitted. Therefore, variables of type pthread_t can't portably be compared using the C equality operator (==); use pthread_equal(3) instead.
Thread identifiers should be considered opaque: any attempt to use a thread ID other than in pthreads calls is nonportable and can lead to unspecified results.
Thread IDs are guaranteed to be unique only within a process. A thread ID may be reused after a terminated thread has been joined, or a detached thread has terminated.
Which means that for example printing the value returned by pthread_self
is not sensible.
Solution 2:
In Linux/GLIBC the pthread_t type is actually the address of the "Thread Control Block" (TCB) of the thread (located at the bottom of its stack). This is unique. But as pointed out in a previous answer from @AnttiHaapala, no supposition can be done as the type should be considered opaque. So, printing it with a "%d" specifier is definitely not portable.
In Linux/GLIBC environment, you also have another unique identifier for a thread. This is its task identifier in the kernel obtained with a call to gettid(). It returns a pid_t typed value (signed integer suitable for "%d" format specifier) as discussed in this post.
Solution 3:
You can use gettid()
. Under Linux, it's available with glibc 2.30 or higher. If you have an older version, you can write your own trivial syscall wrapper.
#include <syscall.h>
static pid_t my_gettid(void)
{
return syscall(SYS_gettid);
}
#define gettid() my_gettid()