Threads Programming in Linux: Examples

One of the important purpose of threads is to achieve concurrency. There may be many independent tasks in a program which can be done in parallel without the influence of the other. One of the first step in using threads is to first recognize the fact whether the program needs threads or not, otherwise the very purpose of threads becomes futile. For example if you are designing a program which involves reading a file and display it, you may utilize two or more threads, one to read the file, the second to update the display and other threads to monitor the user inputs in the form of keyboard interrupts or mouse movements. There can be cases when threads are dependent on each other like in case of our above example, if the concerned application is an editor so a character key pressed should be soon informed to the other thread which updates display so that it may open the menu corresponding to that key shortcut or do some other appropriate action.

Example 1:
Two threads displaying two strings “Hello” and “How are you?” independent of each other.

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

void * thread1()
{
        while(1){
                printf("Hello!!\n");
        }
}

void * thread2()
{
        while(1){
                printf("How are you?\n");
        }
}

int main()
{
        int status;
        pthread_t tid1,tid2;

        pthread_create(&tid1,NULL,thread1,NULL);
        pthread_create(&tid2,NULL,thread2,NULL);
        pthread_join(tid1,NULL);
        pthread_join(tid2,NULL);
        return 0;
}

Now compile this program (Note the -l option is to load the pthread library)

$gcc thread.c -lpthread 

On running, you can see many interleaved “Hello!!” and “How are you?” messages

Example 2
This example involves a reader and a writer thread. The reader thread reads a string from the user and writer thread displays it. This program uses semaphore so as to achieve synchronization

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

char n[1024];
sem_t len;

void * read1()
{
        while(1){
                printf("Enter a string");
                scanf("%s",n);
                sem_post(&len);
        }
}

void * write1()
{
        while(1){
                sem_wait(&len);
                printf("The string entered is :");
                printf("==== %s\n",n);
        }

}

int main()
{
        int status;
        pthread_t tr, tw;

        pthread_create(&tr,NULL,read1,NULL);
        pthread_create(&tw,NULL,write1,NULL);

        pthread_join(tr,NULL);
        pthread_join(tw,NULL);
        return 0;
}

On running, in most cases we may be able to achieve a serial read and write( Thread1reads a string and Thread2 displays the same string). But suppose we insert a sleep function() in write1 like

void * write1()
{
         while(1){
                 sleep(5);
                 sem_wait(&len);
                 printf("The string entered is :");
                 printf("==== %s\n",n);
         }
}

The thread 1 may read one more string and thread2 displays the last read string. That is no serial read and write is achieved.

So we may need to use the condition variables to achieve serial read and write.

Example 3
This example involves a reader and a writer thread. The reader thread reads a string from the user and writer thread displays it. This program uses condition variables to achieve synchronization and achieve serial programming.

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

#define TRUE 1
#define FALSE 0

char n[1024];
pthread_mutex_t lock= PTHREAD_MUTEX_INITIALIZER;
int string_read=FALSE;

pthread_cond_t cond;

void * read1()
{
        while(1){
                while(string_read);
                pthread_mutex_lock(&lock);
                printf("Enter a string: ");
                scanf("%s",n);
                string_read=TRUE;
                pthread_mutex_unlock(&lock);
                pthread_cond_signal(&cond);
        }
}

void * write1()
{
        while(1){
                pthread_mutex_lock(&lock);
                while(!string_read)
                        pthread_cond_wait(&cond,&lock);
                        printf("The string entered is %s\n",n);

                        string_read=FALSE;
                        pthread_mutex_unlock(&lock);
        }
}
int main()
{
        int status;
        pthread_t tr, tw;

        pthread_create(&tr,NULL,read1,NULL);
        pthread_create(&tw,NULL,write1,NULL);

        pthread_join(tr,NULL);
        pthread_join(tw,NULL);
        return 0;
}

The output is serial read and write.

In the beginning, I started the discussion that threads are used to achieve concurrency. But the above examples can be easily done by simple scanf and printf i.e.,
scanf(“%s”,n);
printf(“%s”,n);

But these examples were given to demonstrate the semaphores and condition variables. Example 3 can be further modified to design a reader/writer application. Example string_read boolean variable can be converted to a string_count variable.

 

About these ads

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s