Each thread within a process is uniquely identified by a thread ID. This ID is returned to the caller of pthread_create(), and a thread can obtain its own ID using pthread_self().
include <pthread.h>
pthread_t pthread_self
(void);
Returns the thread ID of the calling thread
Thread IDs are useful within applications for the following reasons:
Various Pthreads functions use thread IDs to identify the thread on which they are to act. Examples of such functions include pthread_join(), pthread_detach(), pthread_cancel(), and pthread_kill(), all of which we describe in this and the following chapters.
In some applications, it can be useful to tag dynamic data structures with the ID of a particular thread. This can serve to identify the thread that created or “owns” a data structure, or can be used by one thread to identify a specific thread that should subsequently do something with that data structure.
The pthread_equal() function allows us check whether two thread IDs are the same.
include <pthread.h>
int pthread_equal
(pthread_t t1, pthread_t t2);
Returns nonzero value if t1 and t2 are equal, otherwise 0
For example, to check if the ID of the calling thread matches a thread ID saved in the variable tid, we could write the following:
if (pthread_equal(tid, pthread_self()) printf("tid matches self\n");
The pthread_equal() function is needed because the pthread_t data type must be treated as opaque data. On Linux, pthread_t happens to be defined as an unsigned long, but on other implementations, it could be a pointer or a structure.
In NPTL, pthread_t is actually a pointer that has been cast to unsigned long.
SUSv3 doesn’t require pthread_t to be implemented as a scalar type; it could be a structure. Therefore, we can’t portably use code such as the following to display a thread ID (though it does work on many implementations, including Linux, and is sometimes useful for debugging purposes):
pthread_t thr; printf("Thread ID = %ld\n", (long) thr); /* WRONG! */
In the Linux threading implementations, thread IDs are unique across processes. However, this is not necessarily the case on other implementations, and SUSv3 explicitly notes that an application can’t portably use a thread ID to identify a thread in another process. SUSv3 also notes that an implementation is permitted to reuse a thread ID after a terminated thread has been joined with pthread_join() or after a detached thread has terminated. (We explain pthread_join() in the next section, and detached threads in Section 29.7.)
POSIX thread IDs are not the same as the thread IDs returned by the Linux-specific gettid() system call. POSIX thread IDs are assigned and maintained by the threading implementation. The thread ID returned by gettid() is a number (similar to a process ID) that is assigned by the kernel. Although each POSIX thread has a unique kernel thread ID in the Linux NPTL threading implementation, an application generally doesn’t need to know about the kernel IDs (and won’t be portable if it depends on knowing them).