1. To initialize a mutex, use below API:
int pthread_mutex_init (pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);
attributes for the mutex can be given through mutexattr, use NULL to use default attributes.
2. To lock a critical section use the below API. This is a blocking call. It means, it will block the calling thread until the lock is acquired.
int pthread_mutex_lock(pthread_mutex_t *mutex)
3. To acquire lock on critical section without blocking use below API:
int pthread_mutex_trylock(pthread_mutex_t *mutex);
4. To unlock the mutex use below API:
int pthread_mutex_unlock(pthread_mutex_t *mutex);
Before we use mutex, let us see the output of below function without thread synchronization:
Example 1:
In the below program I have created 2 threads, both of the threads try to increment the counter. This is called as race condition. It means, 2 threads are racing together to increment the count.
The section where the race condition occurs is called as critical section.
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <pthread.h>
//for more tutorials on C, C++, STL, DS, Linux visit www.ProDeveloperTutorial.com
int counter = 0;
void *myFun()
{
counter++;
printf("Counter value: %d\n",counter);
}
int main()
{
int rc1, rc2;
pthread_t thread1, thread2;
if( (rc1=pthread_create( &thread1, NULL, &myFun, NULL)) )
{
printf("Thread creation failed: %d\n", rc1);
}
if( (rc2=pthread_create( &thread2, NULL, &myFun, NULL)) )
{
printf("Thread creation failed: %d\n", rc2);
}
pthread_join( thread1, NULL);
pthread_join( thread2, NULL);
return 0;
}
Output:
Counter value: 1
Counter value: 1
So as you see from the output, the counter value in both of the cases is 1.
Hence to avoid these kind of errors, we use mutex lock and unlock.
Example 2:
In the below example, I have used mutex lock and mutex unlock.
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <pthread.h>
//for more tutorials on C, C++, STL, DS, Linux visit www.ProDeveloperTutorial.com
int counter = 0;
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
void *myFun()
{
pthread_mutex_lock( &mutex1 );
counter++;
printf("Counter value: %d\n",counter);
pthread_mutex_unlock( &mutex1 );
}
int main()
{
int rc1, rc2;
pthread_t thread1, thread2;
if( (rc1=pthread_create( &thread1, NULL, &myFun, NULL)) )
{
printf("Thread creation failed: %d\n", rc1);
}
if( (rc2=pthread_create( &thread2, NULL, &myFun, NULL)) )
{
printf("Thread creation failed: %d\n", rc2);
}
pthread_join( thread1, NULL);
pthread_join( thread2, NULL);
return 0;
}
Output:
Counter value: 1
Counter value: 2
As you can see from the output above, the value will always return 2.