get thread id in pthread

Thread ID starting from 0 is useful when writing multi-threaded program. In OpenMP, you can simply use omp_get_thread_num() to get the current thread ID. But unfortunately, there is no such thing in PTHREAD. Though pthread_self() returns pthread_t, it does not return an ID starting from 0.

The following code is a simple and naive implementation of GetThreadID() in PTHREAD. By wrapping the standard PTHREAD calls, we are able to provide a mechanism to determine the current thread ID. The code basically uses pthread_key, which is provided by PTHREAD to manipulate data on a per-thread basis, so that we can keep a thread ID for every thread, and easily retrieve the information within each thread. For more information, please refer to PTHREAD specification.

Note: the code actually has several flaws, one of them is that CreateThreadWithID() is not thread-safe. This is because it uses a global variable thread_barrier to synchronize with the child process. But if there are more than one thread trying to perform CreateThreadWithID(), there will be race conditions. I will try to come up with a thread-safe version later, but currently, I am satisfied with it. It meets my purpose, in which a master thread creates all the other slaves.

// MyThread.h
        struct ThreadParam{
                unsigned int id;
                void *(*func)(void *);
                void * arg;

        static pthread_key_t thread_key;
        static pthread_barrier_t thread_barrier;
        static pthread_once_t thread_once=PTHREAD_ONCE_INIT;

        void thread_make_key();
        void * FakeEntry( void * param );
        pthread_t CreateThreadWithID(void *(*func)(void *), void * arg, unsigned int id, const pthread_attr_t * attr);
        int ThreadJoin(pthread_t);
        unsigned int GetThreadID();

// MyThread.cpp
        void thread_make_key(){

        void * FakeEntry(void * param){
                ThreadParam args=*(ThreadParam *)param;
                pthread_once(&thread_once, thread_make_key);
                pthread_setspecific(thread_key, &;

        pthread_t CreateThreadWithID(void *(*func)(void *), void * arg, unsigned int id, const pthread_attr_t * attr){
                ThreadParam param;

                pthread_barrier_init(&thread_barrier, NULL, 2);

                pthread_t thread;
                pthread_create(&thread, attr, FakeEntry, &param);


                return thread;

        int ThreadJoin(pthread_t thread){
                return pthread_join(thread,NULL);

        unsigned int GetThreadID(){
                return *(unsigned int *)pthread_getspecific(thread_key);

// testThread.cpp
#include "MyThread.h"

#include <iostream>
using namespace std;
using namespace HMM_CPU;

const int THREADS=4;

void * foo(void * arg){
        *(int *)arg=GetThreadID();
        return 0;

int main(){
        // create threads
        pthread_t * threads=new pthread_t[THREADS];
        int * ids=new int[THREADS];
        for(int i=0;i<THREADS;i++){
                threads[i]=CreateThreadWithID(foo, &ids[i], i, NULL);

        for(int i=0;i<THREADS;i++){

        delete[] ids;
        delete[] threads;
        return 0;