Mutex
Mutex
The other way of synchronizing access in multithreaded programs is with mutexes (short for mutual
exclusions), which act by allowing the programmer to “lock” an object so that only one thread can
access it. To control access to a critical section of code you lock a mutex before entering the code
section and then unlock it when you have finished.
The basic functions required to use mutexes are very similar to those needed for semaphores. They
are declared as follows:
#include <pthread.h>
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t
*mutexattr);
int pthread_mutex_lock(pthread_mutex_t *mutex));
int pthread_mutex_unlock(pthread_mutex_t *mutex);
int pthread_mutex_destroy(pthread_mutex_t *mutex);
As usual, 0 is returned for success, and on failure an error code is returned, but errno is not set; you
must use the return code. As with semaphores, they all take a pointer to a previously declared
object, in this case a pthread_mutex_t. The extra attribute parameter pthread_mutex_init allows you
to provide attributes for the mutex, which control its behavior. The attribute type by default is
“fast.” This has the slight drawback that, if your program tries to call pthread_mutex_lock on a
mutex that it has already locked, the program will block. Because the thread that holds the lock is
the one that is now blocked, the mutex can never be unlocked and the program is deadlocked. It is
possible to alter the attributes of the mutex so that it either checks for this and returns an error or
acts recursively and allows multiple locks by the same thread if there are the same number of
unlocks afterward.
Task # 2 Mutex
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
int main() {
int res;
pthread_t a_thread;
void *thread_result;
res = pthread_mutex_init(&work_mutex, NULL);
if (res != 0) {
perror("Mutex initialization failed");
exit(EXIT_FAILURE);
}
res = pthread_create(&a_thread, NULL, thread_function, NULL);
if (res != 0) {
perror("Thread creation failed");
exit(EXIT_FAILURE);
}
pthread_mutex_lock(&work_mutex);
printf("Input some text. Enter 'end' to finish\n");
while(!time_to_exit) {
fgets(work_area, WORK_SIZE, stdin);
pthread_mutex_unlock(&work_mutex);
while(1) {
pthread_mutex_lock(&work_mutex);
if (work_area[0] != '\0') {
pthread_mutex_unlock(&work_mutex);
sleep(1);
}
else {
break;
}
}
}
pthread_mutex_unlock(&work_mutex);
printf("\nWaiting for thread to finish...\n");
res = pthread_join(a_thread, &thread_result);
if (res != 0) {
perror("Thread join failed");
exit(EXIT_FAILURE);
}
printf("Thread joined\n");
pthread_mutex_destroy(&work_mutex);
exit(EXIT_SUCCESS);
}