Go4Expert

Go4Expert (http://www.go4expert.com/)
-   C (http://www.go4expert.com/articles/c-tutorials/)
-   -   Unix Threads (Basics) (http://www.go4expert.com/articles/unix-threads-basics-t26726/)

poornaMoksha 18Sep2011 17:29

Unix Threads (Basics)
 
At times certain tasks need more time to execute and when multiple such tasks are desired then blocking on a single task is not a good practice. To Understand, Think of a program that provides some service but this service takes time to execute. Now, if you want this service again and again then every time you may need to wait for the previous request to get complete before you can submit your request which means you even cannot put forward your request until the last request is complete.

Example



For example, the following program asks the user to enter his/her name and does some processing that takes some time. The program commits to serve 5 persons at a time.

Code: C

#include<stdio.h>
#include<string.h>

void doSomeTimConsumingStuff(char* buff)
{
    unsigned long i = 0;

    /** Simulating some time consuming stuff **/
    for(i=0; i<(0xFFFFFFFF);i++);

    printf("\n Mr/Ms %s, your work done\n", buff);
}

int main(void)
{
    int i = 0;

    while(i < 5) // Commiting to serve 5 persons at a time.
    {
        char buff[100];
        memset(buff,'0',sizeof(buff));
        printf("\n Enter your name :");
        scanf("%s",buff); // Use of scanf is discouraged as it opens doors for buffer overflow. Using it for demo purpose only.

        doSomeTimConsumingStuff(buff);
        i++;
    }
    return 0;
}

The problem with above program is that It cannot serve the next person until it is done serving the previous one. So we can say that the call to the function 'doSomeTimConsumingStuff()' is blocking.

The output of the above program is :

Code:

Enter your name :abc

 Mr/Ms abc, your work done

 Enter your name :efg

 Mr/Ms efg, your work done

 Enter your name :ijk

 Mr/Ms ijk, your work done

 Enter your name :lmn

 Mr/Ms lmn, your work done

 Enter your name opq

 Mr/Ms opq, your work done

So now here is an example situation where we can use a concept known as threads. Though with a single processor system the taks will be done serially(at the processor level) but with the help of threads we can make the call to function 'doSomeTimConsumingStuff()' asynchronus by running it in a different thread everytime. So for the users it may seem that their requests are being handled parallely.

For example, the above program can be re-written as :

Code:

#include<stdio.h>
#include<string.h>
#include<pthread.h>
#include<stdlib.h>

void* doSomeTimConsumingStuff(void* buff)
{
        /** Simulating some time consuming stuff **/
        unsigned long i = 0;

        for(i=0; i<(0xFFFFFFFF);i++);

        printf("\n ----------------------------------------> Mr/Ms %s, your work done\n", (char*)buff);

        free(buff);
        return NULL;
}

int main(void)
{
        int i = 0;
        int j = 0;
        pthread_t tid[5];
        int err;
        void* tret = NULL;

        while(i < 5)
        {
                char *buff = (char*)malloc(100);
                memset(buff,'0',sizeof(100));

                printf("\n Enter your name :");
                scanf("%s",buff);

                err = pthread_create(&(tid[i]), NULL, &doSomeTimConsumingStuff, buff);
                if (err != 0)
                        printf("\ncan't process your request: %s\n", strerror(err));
                else
                        printf("\n Thanks Mr/Ms [%s] for the request, your request is under processing, will notify you when its done\n", buff);

                i++;
        }
        for(j = 0;j<5;j++)
        {
                err = pthread_join(tid[j], &tret);
                if (err != 0)
                        printf("\n can't process the request: %s\n", strerror(err));
        }

        return 0;
}

In the above program, the program takes the input, notifies that the request is under processing by creating a new thread and is ready to accept another request. So the user is not blocked while providing input.

The output of the above program comes out as :

Code:

Enter your name :abc

 Thanks Mr/Ms [abc] for the request, your request is under processing, will notify you when its done

 Enter your name :efg

 Thanks Mr/Ms [efg] for the request, your request is under processing, will notify you when its done

 Enter your name :ijk

 Thanks Mr/Ms [ijk] for the request, your request is under processing, will notify you when its done

 Enter your name :lmn

 Thanks Mr/Ms [lmn] for the request, your request is under processing, will notify you when its done

 Enter your name opq

 Thanks Mr/Ms [opq] for the request, your request is under processing, will notify you when its done

 ----------------------------------------> Mr/Ms efg, your work done

 ----------------------------------------> Mr/Ms abc, your work done

 ----------------------------------------> Mr/Ms lmn, your work done

 ----------------------------------------> Mr/Ms ijk, your work done

 ----------------------------------------> Mr/Ms opq, your work done

So, as you can see above, the user is not blocked to provide input.

Change Set



So, we made our program asynchronus from synchronus and the steps involved were
  • Include the header 'pthread.h'.
  • Changed the signature of the function 'doSomeTimConsumingStuff()' from void doSomeTimConsumingStuff(char*) to void* doSomeTimConsumingStuff(void*) as the pthread_create API requires a pointer to (void*)(*)(void*) kind of a function.
  • Introduced a call to 'pthread_create()' that creates a new thread.
  • Introduced a call to 'pthread_join()' that makes sure that the parent thread (Original thread in which main() is being run) does not get over before all the threads created by pthread_create() are done with their respective processing.
  • Last but not the least, compile the program with '-lpthread' flag in order to link to pthread library.
For details about thread APIs, Will write an article on that too. Stay tuned for more...


All times are GMT +5.5. The time now is 10:07.