Let us learn posix thread synchronization in c with example. posix thread synchronization is an important part of multi threaded programming. There are various techniques to synchronize threads for example locking , mutex, semaphore etc. Here we will learn how to synchronize threads using mutex. mutex provides lock and unlock method. lock prevents a thread to execute specific part of a program. when a thread finishes its execution it unlocks mutex. 

Let us write a simple code which is not a multithreading program.

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

int counter = 0;

void doJobs()
{
    counter = 0;
    for(int i=0; i < 3; i++)
    {
      printf("%d ",counter++);
    }
}

int main(void)
{
    // call doJobs 3 times
    for(int i=0; i < 3; i++)
    {
       doJobs();
    }
    printf("\n");
    return 0;
}

Output of above would be 0 1 2 0 1 2 0 1 2 and it is obvious.

Let us change the above code and call doJobs() function with threads.We will create 3 threads and each thread will execute function doJobs().

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

int counter = 0;

void* doJobs(void *arg)
{
    counter = 0;
    for(int i=0; i < 3; i++)
    {
      printf("%d ",counter++);
    }    
    
    return NULL;
}

int main(void)
{
    int i = 0;
    int err;

    pthread_t tid[3];

    // create three threads
    for(int i=0; i < 3; i++)
    {
        err = pthread_create(&(tid[i]), NULL, doJobs, NULL);
        if (err != 0)
            printf("Fail to create thread :[%s]", strerror(err));
    }

    // join all threads
    for(int i=0; i < 3; i++)
    {
        pthread_join(tid[i], NULL);
    }
    printf("\n");
    return 0;
}

Save the above code as sample.c and compile using ‘gcc sample.c -osample -lpthread’. when we run the program it will print something like 0 1 2 0 3 4 0 5 6 and sometime it will print 0 1 2 0 1 2 0 1 2.

What is issue with the above multi-threaded code?

Let see our doJobs function

thread synchronization in c

In our program counter is a global variable. in the start of doJobs() function counter is being reset and then in for loop we are printing  counter++. we have created 3 threads,suppose one thread is executing print statement, incrementing the counter variable, when other threads would enter into the doJobs() function,it would find the optimized value of counter. so the real issue is counter variable, which is not synchronized.

 Let us use mutex  to make doJobs() function to synchronize threads.

Sample code for thread synchronization in c

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

int counter = 0;

pthread_mutex_t lock;

void* doJobs(void *arg)
{
    pthread_mutex_lock(&lock);

    counter = 0;
    for(int i=0; i < 3; i++)
    {
      printf("%d ",counter++);
    }

    pthread_mutex_unlock(&lock);
    
    return NULL;
}

int main(void)
{
    int err;

    pthread_t tid[3];

    if (pthread_mutex_init(&lock, NULL) != 0)
    {
        printf("\n mutex initalization failed\n");
        return -1;
    }

    // create three threads
    for(int i=0; i < 3; i++)
    {
        err = pthread_create(&(tid[i]), NULL, doJobs, NULL);
        if (err != 0)
            printf("Fail to create thread :[%s]", strerror(err));
    }

    // join all threads
    for(int i=0; i < 3; i++)
    {
        pthread_join(tid[i], NULL);
    }
    printf("\n");

    pthread_mutex_destroy(&lock);

    return 0;
}

compile above program using
gcc -std=c99 -g a.c -lpthread

Now whenever we run above program , it will always print 0 1 2 0 1 2 0 1 2

How it works

  • A mutex is initialized in the beginning of the main function using pthread_mutex_init.
  • The mutex (loc) islocked in the ‘doJobs()’ function in the begining.
  • At the end of the function ‘doJobs()’ the mutex is unlocked.
  • when all threads finishes their execution ,mutext is destroyed using     pthread_mutex_destroy(&lock);

Ref:

http://www.tutorialspoint.com/articles/syncronization-in-threads-using-posix-thread



Related Contents to follow