In Mutua_esclusione abbiamo parlato di race condition di mutex.
Consideriamo un esempio base di race condition :
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
int counter = 0;
void* increment_counter(){
for(int i=0; i < 1000000; i++){
counter++;
}
}
int main(int argc, char* argv[]){
pthread_t t1, t2;
pthread_create(&t1, NULL, &increment_counter, NULL);
pthread_create(&t2, NULL, &increment_counter, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
printf("Counter is %d\n", counter);
return 0;
}il programma crea 2 thread che eseguono (in parallelo) l’incremento di 1,000,000 volte il counter, quindi dovrebbe essere alla fine 2,000,000… e invece se lo eseguivamo otteniamo valori diversi. Questo è un classico esempio di race condition sulla variabile counter.
Per risolvere il problema utilizziamo i mutex. Dichiariamo prima una variabile che farà da mutex :
int count = 0;
pthread_mutex_t mutex;poi la inizializziamo prima di creare i threads, con pthread_mutex_init che prende come parametri :
- puntatore oggetto mutex utilizzato (
mutex) - attributi per il mutex utilizzato
pthread_t t1, t2;
pthread_mutex_init(&mutex, NULL);Ricordiamoci alla fine di “distruggere” il mutex :
pthread_mutex_destroy(&mutex);
printf("Counter is %d\n", counter);A questo punto siamo liberi di utilizzare il mutex, e lo facciamo in questo caso “attorno” alla variabile critica contestata e al suo incremento :
for(int i=0; i < 1000000; i++){
pthread_mutex_lock(&mutex); // acquisisci il mutex
counter++;
pthread_mutex_unlock(&mutex); // rilascia il mutex
}In questo modo otteniamo il risultato atteso :

