Mutual Exclusion (Mutex)
Given the following code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#define NB_THREADS 5
typedef struct {
int n;
} data;
void print_char_by_char(char *s, int n) {
int i = 0;
while (s[i] != '\0') {
printf("%c", s[i]);
fflush(stdout); // Forcing stdout to be displayed
i++;
// Sleep for 0.5 second
struct timespec tim, tim2;
tim.tv_sec = 0;
tim.tv_nsec = 500000000L;
nanosleep(&tim , &tim2);
}
printf("%d \n", n);
sleep(1);
}
void *mytask(void *p_data) {
char *message = "Thread_n ";
data *info = p_data;
print_char_by_char(message, info->n);
}
int main(void) {
printf("main start\n");
int i;
pthread_t threads[NB_THREADS];
data infos[NB_THREADS];
for (i = 0; i < NB_THREADS; i++) {
infos[i].n = i;
pthread_create(&threads[i], NULL, mytask, &infos[i]);
}
for (i = 0; i < NB_THREADS; i++) {
pthread_join(threads[i], NULL);
}
printf("main end\n");
}
- Compile and run this program. What is outputted on the standard output? Explain.
- Use a mutex so that every thread can display the message correctly: only one thread can be printing on stdout at a time.
Here is some help to manage mutex :
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // Create a mutex
pthread_mutex_lock(&mutex); // Get the mutex (locking every other callers)
pthread_mutex_unlock(&mutex); // Release the mutex (Unlock one caller)
Note: Mutex needs to be initialized in a global variable so that every thread can access it.
Semaphores
Update the previous program and use a semaphore instead of a mutex.
Here is some help to manage semaphores:
#define SEMNAME "monsem"
sem_t *attente;
attente = sem_open(SEMNAME, O_CREAT|O_EXCL, 0777, 1); // Create the semaphore
if(attente == SEM_FAILED) {
perror("unable to create semaphore");
sem_unlink(SEMNAME);
exit( -1 );
}
sem_wait(attente); // Decrease the semaphore counter
sem_post(attente); // Increase the semaphore counter
sem_close(attente); // Close the semaphore
sem_unlink(SEMNAME); // unlink the semaphore
Synchronization barrier
Create a program where 10 threads are executed. Each thread will sleep for a random time. Then each thread will wait for others using a semaphore. The last thread will wake all others so they can end normally.
Hint: You have to use one semaphore, one mutex and one global variable to to that.
Algorithm
// Considering there are N process / threads
// Considering Semaphore is initialized to 0
Lock(MUTEX)
finished_threads++;
if (finished_threads == N) {
for (int i = 0; i < N -1; i++) {
Post(Semaphore);
}
finished_threads = 0;
Unlock(MUTEX)
} else {
Unlock(MUTEX)
Wait(Semaphore)
}