MultiThreading in C Tutorial - Part 7 Mutex
Mutexes are used to provide exclusive access to a shared resource .Mutex stands for Mutual Exclusion.
POSIX API's for Mutex:
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
This function initializes the mutex with the attributes passed in the second argument.If the second argument is NULL then default attributes are applied.Upon successful initialization, the state of the mutex will be initialized and unlocked.
int pthread_mutex_destroy(pthread_mutex_t *destroy);
It is used to destroy the mutex specified in the argument and its state become uninitialized.Once destroyed you can still use it to reinitialize.Note that if you are trying to destroy the mutex when it is locked it will result in undefined behaviour.
If you want a mutex with default attributes, the macro PTHREAD_MUTEX_INITIALIZER can be used.
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
The above statement is similar to calling pthread_mutex_init with second argument set to NULL, except that you are not performing any error checking.
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
Both the API's are used to lock and unlock the corresponding mutex.If the mutex state is locked and if you call pthread_mutex_lock the thread will be in the blocking state until the mutex is unlocked.
int pthread_mutex_trylock(pthread_mutex_t *mutex);
This function is similar to pthread_mutex_lock except that if the lock is not available it will be not be blocked as pthread_mutex_lock.
On SUCCESS, both of the functions return zero, else it returns an error value.
We will see an example code to understand this.
#include <stdio.h>
#include <pthread.h>
int counter = 0;
pthread_t tid[2];
pthread_mutex_t mutex ;
void *threadFn(void *arg)
{
pthread_mutex_lock(&mutex);
counter += 1;
printf("Job %d started\n", counter);
sleep(1);
printf("Job %d Finished\n", counter);
pthread_mutex_unlock(&mutex);
pthread_exit(NULL);
}
int main(int argc,char *argv[])
{
int ret, i;
ret = pthread_mutex_init(&mutex, NULL);
if (ret != 0) {
perror("Error creating Mutex\n");
exit(1);
}
for (i = 0; i < 2;i++) {
ret = pthread_create(&tid[i], NULL, threadFn, NULL);
if (ret != 0) {
perror("Error in creating threads\n");
exit(1);
}
}
pthread_join(tid[0], NULL);
pthread_join(tid[1], NULL);
pthread_mutex_destroy(&mutex);
pthread_exit(NULL);
}
O/P:
Job 1 started
Job 1 Finished
Job 2 started
Job 2 Finished
POSIX API's for Mutex:
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
This function initializes the mutex with the attributes passed in the second argument.If the second argument is NULL then default attributes are applied.Upon successful initialization, the state of the mutex will be initialized and unlocked.
int pthread_mutex_destroy(pthread_mutex_t *destroy);
It is used to destroy the mutex specified in the argument and its state become uninitialized.Once destroyed you can still use it to reinitialize.Note that if you are trying to destroy the mutex when it is locked it will result in undefined behaviour.
If you want a mutex with default attributes, the macro PTHREAD_MUTEX_INITIALIZER can be used.
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
The above statement is similar to calling pthread_mutex_init with second argument set to NULL, except that you are not performing any error checking.
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
Both the API's are used to lock and unlock the corresponding mutex.If the mutex state is locked and if you call pthread_mutex_lock the thread will be in the blocking state until the mutex is unlocked.
int pthread_mutex_trylock(pthread_mutex_t *mutex);
This function is similar to pthread_mutex_lock except that if the lock is not available it will be not be blocked as pthread_mutex_lock.
On SUCCESS, both of the functions return zero, else it returns an error value.
We will see an example code to understand this.
#include <stdio.h>
#include <pthread.h>
int counter = 0;
pthread_t tid[2];
pthread_mutex_t mutex ;
void *threadFn(void *arg)
{
pthread_mutex_lock(&mutex);
counter += 1;
printf("Job %d started\n", counter);
sleep(1);
printf("Job %d Finished\n", counter);
pthread_mutex_unlock(&mutex);
pthread_exit(NULL);
}
int main(int argc,char *argv[])
{
int ret, i;
ret = pthread_mutex_init(&mutex, NULL);
if (ret != 0) {
perror("Error creating Mutex\n");
exit(1);
}
for (i = 0; i < 2;i++) {
ret = pthread_create(&tid[i], NULL, threadFn, NULL);
if (ret != 0) {
perror("Error in creating threads\n");
exit(1);
}
}
pthread_join(tid[0], NULL);
pthread_join(tid[1], NULL);
pthread_mutex_destroy(&mutex);
pthread_exit(NULL);
}
O/P:
Job 1 started
Job 1 Finished
Job 2 started
Job 2 Finished
Comments
Post a Comment