The thread ID returned by pthread_self() is not the same thing as the kernel thread ID returned by a call to gettid(2)

So, on what basis should I decide whether I should use pthread_self or gettid to determine which thread is running the function?

You should always use pthread_self() whenever you want to identify a thread within your application. gettid() can be used for certain purposes and if you know it's Linux. For example, gettid() can be used to get seed for a thread specific seed (used in srand()).

Both are non portable.

This is not entirely true. gettid() is not portable as its a Linux specific function. But pthread_self() is portable as long as you don't make any assumptions about its representation.

For example, the following is not portable.

printf("Thread ID is: %ld", (long) pthread_self());

as there's no guarantee that whatever pthread_self() is going to be an integer of some sort. But

pthread_t my_tid; //filled elsewhere

pthread_t tid = pthread_self();

if( pthread_equal(my_tid, tid) ) {
   /* do stuff */
}

is fully portable.

The former is not portable because it assumes that thread id is an integer whereas the latter is not.

Why are there two different functions to get the thread ID?

They are not two different ways to get the same value. One (pthread_self() is provided by the thread library (pthreads) while the other (gettid()is an OS-specific function. A different OS may provide a different interface/syscall to get thread ID similar to gettid(). So you can't rely on gettid() in a portable application.


pthread_self() returns the process-wide unique pthread-id.

gettid() returns the (pthread implementation specific) system-wide unique thread-id (on Linux).

the TID(thread id) returned by gettid() is unique inside a process

Yes.

(or inside a program with multiple processes,

Yes.

inside a process, different thread has different thread id.

Yes.

the TID returned by pthread_self() is unique across processes,

No.

different thread has different TID on the same machine at the same time.

Yes in the same process, No across the whole machine.

As gettid() is Linux specific and therefore not portable, the only way to system widely identify a pthread is to use its (system wide unique) parent process id as returned by getpid() along with its (process-wide unique) pthread-id as returned by pthread_self().


This is an interesting study in the difference between conceptual terminology and real software entities (which belong to specific software abstractions).

First of all, pay attention to the types of these two calls.

pid_t gettid(void);
pthread_t pthread_self(void);

One is pid_t and the other is pthread_t. Both of these refer to a common conceptual entity called a thread, but the different types imply that these are two different software entities. They are different representations of a thread id, and make sense within the software abstraction that incorporates it. So, pthread_t makes sense only within the abstraction supported by the pthread package, and pid_t makes sense within the abstraction that incorporates this type (i.e. Linux system calls that deal in pid_t).

You should be using the correct type based on the context. Use pthread_t in the context which requires the type pthread_t and pid_t in the context which requires pid_t - regardless of the fact that they might refer to the same thread.

Each one of these contexts have prescribed syntax for comparison and equality. pid_t can be directly compared by the == operator, while pthread_t must be compared by invoking pthread_equal.

The reason for this dual representation / software abstractions is that the pthread library is a portable thread library that can be implemented on different operating systems. Different implementations of the pthread library guarantee that the thread id type will always be pthread_t. These threads may underneath map to a operating system specific thread entity whose OS identifier depends on the operating system (e.g. for Linux it is pid_t; for Windows it is DWORD).

So, while the underlying implementation may differ from OS to OS, the code written against the pthread abstraction remains portable across OSes (as long as you confine yourself to the pthread abstraction).