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).