How to obtain a unique thread identifier on Linux

Thread ID From some reason this topic never got enough attention in libc. POSIX threads library does addresses this issue, however what starts in POSIX library stays in POSIX library. pthread_self() and friends will get you an identifier that is unique accross your program, but not accross your system. Although thread is a system object, the system is unaware of the identifier POSIX library allocated for the thread. Thus the thread identifier allocated by the POSIX library does identify your thread within boundaries of your program, yet every-one else knows nothing about this identifier and its meaning.

On the contrary, Linux identifies threads with PID like number called TID. These numbers are system-wide. Tools like htop understand them and allow you to obtain information for each and every thread.

In Linux, there’s a system call that will return a TID of calling thread. The name of the system call is gettid(). From some reason it is not implemented in glibc. Probably it is because it is Linux specific system call. Anyway you have to use syscall() to call it. Here’s a sample code that does exactly this.

#include <stdio.h>
#include <linux/unistd.h>
#include <sys/syscall.h>
#include <unistd.h>

pid_t gettid( void )
{
        return syscall( __NR_gettid );
}

int main()
{
        printf( "My TID is %d\n", (int)gettid() );
        return 0;
}

Did you know that you can receive periodical updates with the latest articles that I write right into your email box? Alternatively, you subscribe to the RSS feed!

Want to know how? Check out
Subscribe page

11 Comments

  1. Jeff Frontz says:

    Also, the value returned by pthread_self() can be reused across your program; it only uniquely identifies *existing* threads. Thus, if a thread is destroyed and a new thread is subsequently created, the destroyed and newly created thread may have [had] the same pthread_self() return values.

  2. Alexander Sandler says:

    Good point! You are absolutely right.

  3. Peakkideles says:

    I am here at a forum newcomer. Until I read and deal with the forum.
    Let’s learn!

  4. Andre Goddard Rosa says:

    Hi, Alexander!

    A small nitpick:

    > These numbers are system-wide

    I think they are not system-wide. from linux-2.6/include/linux/sched.h:

    /*
    * the helpers to get the task’s different pids as they are seen
    * from various namespaces
    *
    * task_xid_nr() : global id, i.e. the id seen from the init namespace;
    * task_xid_vnr() : virtual id, i.e. the id seen from the pid namespace of
    * current.

    So, I think they are unique for that process, like pthread values, not system-wide.

    By looking at a thread running on my system:

    ├─chrome(7724)─┬─chrome(7727)─┬─{chrome}(7728)

    Under /proc, I have:
    7723/ 7724/ 7727/

    So, 7728, which is a thread created by process 7727 is not listed under /proc/7728, but instead under /proc/7727/task/7728/

    p.s.: this is chrome browser, taken from here http://build.chromium.org/buildbot/snapshots/chromium-rel-linux/

  5. Andre Goddard Rosa says:

    I have to check further, because apparently it’s under system-wide namespaces because it avoids creating new processes using that same TID used for thread. As threads are a special process anyway, created with clone(CLONE_THREAD), perhaps they are system-wide indeed. Or.. in case PIDs are running out, TIDs could be reused as PIDs… Have to check! :)

  6. Andre Goddard Rosa says:

    hehe, checking man clone:

    “The threads within a group can be distinguished by their (system-wide) unique thread IDs (TID).”

    Sorry for the noise, my bad. :-P

  7. Originally Posted By Andre Goddard Rosa
    hehe, checking man clone:

    “The threads within a group can be distinguished by their (system-wide) unique thread IDs (TID).”

    Sorry for the noise, my bad. :-P

    No problem :-)

    On thing that you’ve missed is that chrome uses multiple processes, one for each web-site and not multiple threads.
    If you do want to see thread IDs, check out /proc/ /task/
    This is where you’ll find directory for each thread.

  8. Andre Goddard Rosa says:

    @Alexander Sandler

    Yes, I know, actually it uses both processes and threads, although the main design is based on IPC between multiple processes.

    As I mentioned before, that one specifically was a thread:

    > So, 7728, which is a thread created by process 7727 is not listed
    > under /proc/7728, but instead under /proc/7727/task/7728/

    ;-)

  9. sandrar says:

    Hi! I was surfing and found your blog post… nice! I love your blog. :) Cheers! Sandra. R.

Leave a Reply


6 − = four