Tuesday, August 13, 2013

gettid() vs pthread_self()

So we have looked at both gettid(getting the id of the thread) and the pthread_self(),Now let us join then as see the output...so the difference between then is clear...

#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<linux/unistd.h>
#include<sys/syscall.h>
void* printid(void *ptr)
{
printf("The id of %s is %u\n",(char*)ptr,syscall( __NR_gettid ));
printf("The id of %s is %u\n",(char*)ptr,(unsigned int)pthread_self());
}
int main()
{
    pthread_t thread[5];
    char *msg[]={"thread1","thread2","thread3","thread4","thread5"};
    int i;
    for(i=0;i<5;i++)
    {
        pthread_create(&thread[i],NULL,printid,(void*)msg[i]);
        pthread_join(thread[i],NULL);
    }
    return 0;
}
output:
The id of thread1 is 18799
The id of thread1 is 3086543760
The id of thread2 is 18800
The id of thread2 is 3086543760
The id of thread3 is 18801
The id of thread3 is 3086543760
The id of thread4 is 18802
The id of thread4 is 3086543760
The id of thread5 is 18803
The id of thread5 is 3086543760
Explanation:
As you can see the ID generated by pthread_self() is reused by the threading implementation after the thread completion which have achieved using the join in the for loop..and the ID assigned by the kernel is unique one...
So the difference between gettid() and the pthread_self() is:
1.)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.
2.)ID generated by the pthread_self() can be used after the completion of the thread but  the ID genereated by the kernel can't be used even after the completion of the thread..

Getting the Thread ID In C

As we have see in the pthread_self(),the ID is implemented or maintained by threading implementation not by the kernel,so for getting the unique ID assiged by the kernel we have to use the system call...
Take a look at the example...
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<linux/unistd.h>
#include<sys/syscall.h>
void* printid(void *ptr)
{
printf("The id of %s is %u\n",(char*)ptr,syscall( __NR_gettid ));
}
int main()
{
    pthread_t thread[5];
    char *msg[]={"thread1","thread2","thread3","thread4","thread5"};
    int i;
    for(i=0;i<5;i++)
    {
        pthread_create(&thread[i],NULL,printid,(void*)msg[i]);
        pthread_join(thread[i],NULL);
    }
    return 0;
}
output:
On my system the output is:
The id of thread1 is 18622
The id of thread2 is 18623
The id of thread3 is 18624
The id of thread4 is 18625
The id of thread5 is 18626
As you can see now the IDs are different because they are assigned by the kernel not by the threading implementation...

pthread_self()

Getting the Thread ID..
We can get the ID of the thread by using the funciton pthread_self() on the running thread.
The main point about this function is :It uniquely identifies EXISTING threads,Here EXISTINGhas a special meaning..The meaning is pthread_self() return the value which can be reused across the program that means if you have created a thread and it completed its execution then the id of that thread can be used as the id of another thread..
Let us prove the statement that is a thread completes then the id of that thread(returned by pthread_self) can be used as the id of another thread...
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<linux/unistd.h>
#include<sys/syscall.h>
void* printid(void *ptr)
{
printf("The id of %s is %u\n",(char*)ptr,(unsigned int)pthread_self());
}
int main()
{
    pthread_t thread[5];
    char *msg[]={"thread1","thread2","thread3","thread4","thread5"};
    int i;
    for(i=0;i<5;i++)
    {
        pthread_create(&thread[i],NULL,printid,(void*)msg[i]);
        pthread_join(thread[i],NULL);
    }
    return 0;
}
output:
On my system the output is:
The id of thread1 is 3086285712
The id of thread2 is 3086285712
The id of thread3 is 3086285712
The id of thread4 is 3086285712
The id of thread5 is 3086285712
As you can see the ID's of all the thread is equal...
Explanation:I need to explain only one thing that is how to make sure that a thread completes before the execution of the next thread the answer is simple joining the thread solves our purpose..so in the for loop we create a thread then call a join so the main program waits for the thread to complete for the next iteration of the for loop..In this way we can make sure that the thread starts after the completion of the previous thread...
As the thread completes so the program can use the same ID of thread1 for the thread2 and so on....
Why so???
POSIX thread IDs are assigned and maintained by the threading implementation not by the kernel,to get the ID assigned by the kernel see here...

Thread Specific Data Example

Here is the Example to using Thread Specific Data..
In this example I am using File pointer as the TSD,setting the value of the key and then getting the correspoding file pointer for the particular thread...
Each Thread creates its log file and writes its name in the file....
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
static pthread_key_t key;
void write_to_file(void *ptr)
{
    FILE *fp= (FILE*)pthread_getspecific(key);
    fprintf(fp,"%s",(char*)ptr);
        fclose(fp);
}
void* perform(void *ptr)
{
    FILE *fp;
    char *filename=malloc(strlen((char*)ptr)+8 );
    sprintf(filename,"%slog.log",(char*)ptr);
    fp=fopen(filename,"w");
    pthread_setspecific(key,fp);
    write_to_file(ptr);
}
int main()
{
    pthread_t thread[5];
    char *msg[]={"thread1","thread2","thread3","thread4","thread5"};
    int i;
    pthread_key_create(&key,NULL);
    for(i=0;i<5;i++)
    {
        pthread_create(&thread[i],NULL,perform,(void*)msg[i]);
        pthread_join(thread[i],NULL);
    }
    printf("Now main ends");
    return 0;
}

Thread Specific Data

Thread Specific Data
Thread Specific Data means data related to a particular thread,Think of a pool of different data for different threads that each thread can access with a public key...
All things revolves around a key to get the particular data..
what to do--
1.)Create a key
2.)set the specific data for the thread using the key
3.)get the specific data using the key only for a specific thread
Example:suppose there are 4 Threads running and every threads has to create a log file of the task that is performing,so each thread wants a file pointer specific to that thread so we can keep those file pointers as the TSD and can use a key to access the TSD for each thread..
For creating a key use the following function:
int pthread_key_create(pthread_key_t *key, void (*destructor) (void *));
first argument-The key which you have defined...
second argument-The function which you want to run after the completion of the thread,generally for cleanup,descrutor kind of thing.
Note-If you pass a function pointer here, GNU/Linux automatically calls that function when each thread exits, passing the thread-specific value corresponding to that key. This is particularly handy because the cleanup function is called even if the thread is canceled at some arbitrary point in its execution. If the thread-specific value is null, the thread cleanup function is not called. If you don't need a cleanup function, you may pass NULL instead of a function pointer.
For setting the value use the following function:
pthread_setspecific(key, value);
For getting the value use the following function:
pthread_getspecific(key);

Return Value From Thread

As we have seen in the examples the return type of the functions that runs as the threads is the void*,it means we can return a value from the thread,but the point is how to capture that returned value in the main function...
The answer is the join again,as we have seen in the join the function prototype is
int pthread_join(pthread_t,void **)
Here the 2nd argument is the pointer to the value returned by the thread...
In the main funtion we can capture and use the value returned by the thread using the pthread_join.

Let us capture the return value...
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
void* myfunc1(void *ptr)
{
    char *msg;
    int i=0;
    msg=(char*)ptr;
    while(1)
    {
        sleep(1);
        if(i>5)
            break;
        else
        {
            printf("i in thread1=%d\n",i);i++;
        }
    }
    printf("Thread1 completed\n");
    return "hello";
}
void *myfunc2(void *ptr)
{
    char *msg;
    int i=0;
    msg=(char*)ptr;
    while(1)
    {
        sleep(1);
        if(i>10)
            break;
        else
        {
            printf("i in thread2=%d\n",i);i++;
        }
    }
    printf("Thread2 completed\n");
    return "Hi";
}
int main()
{
    pthread_t thread1,thread2;
    int val1,val2;
    int status;
    char *msg1="Thread1";
    char *msg2="Thread2";
    void **ret_val1=malloc(sizeof(void*));
    void **ret_val2=malloc(sizeof(void*));
    printf("In the main funciton\n");
    pthread_create(&thread1,NULL,myfunc1,(void*)msg1);
    pthread_create(&thread2,NULL,myfunc2,(void*)msg2);
    pthread_join(thread1,ret_val1);
    pthread_join(thread2,ret_val2);
    printf("return value from thread1  is:%s\n",*ret_val1);
    printf("return value from thread2 is:%s\n",*ret_val2);
    printf("Now main ends");
    return 0;
}

Thread Join In C

Why thread Join??
As we have seen in the first multithreaded program that we have the while(1) loop in the main function ,that is to ensure that the application/program keeps runnning because if main ends the program ends...
Now if we dun want to waste the time in the main program and only want to run the threads we can use the thread join to achieve this task.

what is a join??
Join means we are telling the thread to join with the other thread that is we are telling that wait for the other thread to finish..
So two threads are included in the join
first thread -to whom we are saying to join
second thread-the thread to join with
suppose there is Thread1 and Thread2,and we require the Thread2 must complete before Thread1 so we have to tell the Thread1 to join with the Thread2..
So in our Example,We have to say main to join with the Thread1 and Thread2 ,that is telling main to wait for both the Threads to complete,
So, By using join we need not to worry about the main,the main will end only after the completion of the both threads..


Funtion prototype:
int pthread_join(pthread_t tid, void **status);
The first argument is the thread ID.
The second argument is a pointer to the data your thread function returned,keep it as NULL for now.

Example:
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
void* myfunc1(void *ptr)
{
    char *msg;
    int i=0;
    msg= (char*)ptr;
    while(1)
    {
        printf("In the %s\n",msg);
        sleep(1);
    if(i++> 7)
    break;
    }
printf("Thread1 completed\n");
}
void *myfunc2(void *ptr)
{
    char *msg;
    int i=0;
    msg= (char*)ptr;
    while(1)
    {
        printf("In the %s\n",msg);
        sleep(1);
    if(i++>10 )
    break;
    }
printf("Thread2 completed\n");
}
int main()
{
    pthread_t thread1,thread2;
    int val1,val2;
    int status;
    char *msg1="Thread1";
    char *msg2="Thread2";
    void **ret_val;
    printf("In the main funciton\n");
    val1=pthread_create(&thread1,NULL,myfunc1,(void*)msg1);
    val2=pthread_create(&thread2,NULL,myfunc2,(void*)msg2);
    printf("the value returned by thread1=%d\n",val1);
    printf("the value returned by thread2=%d\n",val2);
    pthread_join(thread1,NULL);//telling main to join with thread1
    pthread_join(thread2,NULL);//telling main to join with thread2
        printf("Now main ends:\n");
    return 0;
}

First Multi Threaded Program in C

Today i have written my first multithreaded program in C on linux,
It is very easy to write multithreded program using the pthread library..
Let us take a look which function we need to create a multithreded program in c...

The function to create the thread:
int pthread_create(pthread_t *tid,const pthread_attr_t *attr,void *(*func)(void *), void *arg)
Note-Each thread will have its own unique thread ID.

The first argument is the variable where its thread ID will be stored. 
The second argument contains attributes describing the thread. Keep this as NULL now,will explain later.
The third argument is a pointer to the function you want to run as a thread.
The final argument is a pointer to data you want to pass to the function.

Having this information in mind you can write a simple multithreaded program in C...

Let us take a look at a example:
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
void* myfunc1(void *ptr)
{
char *msg;
msg= (char*)ptr;
printf("%s started\n",msg);
while(1)
{
printf("In the %s\n",msg);
sleep(1);
}
}
void *myfunc2(void *ptr)
{
char *msg;
msg= (char*)ptr;
printf("%s started\n",msg);
while(1)
{
printf("In the %s\n",msg);
sleep(1);
}
}
int main()
{
pthread_t thread1,thread2;
int val1,val2;
char *msg1="Thread1";
char *msg2="Thread2";
printf("In the main funciton\n");
printf("My first thread program\n");
val1= pthread_create(&thread1,NULL,myfunc1,(void*)msg1);
val2= pthread_create(&thread2,NULL,myfunc2,(void*)msg2);
printf("The value returned by thread1=%d\n",val1);
printf("The value returned by thread2=%d\n",val2);
while(1)
{
printf("in the main function\n");
sleep(1);
}
return 0;
}