pthreads
Condizioni di gara in pthreads
Ricerca…
introduzione
Esempio: Consider avrà due thread T1 e T2.
Come li riconosci?
Se la stessa variabile / risorsa / posizione di memoria è accessibile da più thread e almeno il thread sta cambiando il valore di variabile / risorsa / posizione di memoria , allora si può verificare la condizione di gara . Perché se un thread sta cambiando il valore di variabile / risorsa / posizione di memoria e un altro thread tenta di leggere lo stesso, non otterrà il valore aggiornato.
Nota : se tutti i thread stanno leggendo solo la variabile / risorsa / posizione di memoria, la condizione di gara non si verificherà.
Esempio: il programma soffre delle condizioni della gara
#include <stdio.h>
#include <pthread.h>
int x= 0;
void* fun(void* in)
{
int i;
for ( i = 0; i < 10000000; i++ )
{
x++;
}
}
int main()
{
pthread_t t1, t2;
printf("Point 1 >> X is: %d\n", x);
pthread_create(&t1, NULL, fun, NULL);
pthread_create(&t2, NULL, fun, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
printf("Point 2 >> X is: %d\n", x);
return 0;
}
L'output sul mio schermo è:
Point 1 >> X is: 0
Point 2 >> X is: 9925047
Il tuo output varierà. Ma di sicuro non saranno 20.000.000. Poiché entrambi Thread eseguono lo stesso ciclo e hanno una variabile globale int x;
for ( i = 0; i < 10000000; i++ )
{
x++;
}
Quindi il valore finale di x nel Point 2 >> X is: 9925047 linea Point 2 >> X is: 9925047 dovrebbe essere 20.000.000. Ma non è così.
Lo stato di x può essere modificato da un altro thread durante il tempo tra x viene letto e quando viene riscritto.
Diciamo che un thread recupera il valore di x, ma non lo ha ancora memorizzato. Un altro thread può anche recuperare lo stesso valore di x (perché nessun thread lo ha ancora modificato) e quindi entrambi avrebbero memorizzato lo stesso valore (x + 1) in x!
Esempio:
Discussione 1: legge x, il valore è 7
Thread 1: aggiungi 1 a x, il valore ora è 8
Thread 2: legge x, il valore è 7
Discussione 1: memorizza 8 in x
Thread 2: aggiunge 1 a x, il valore ora è 8
Thread 2: memorizza 8 in x
Come li gestisci?
Le condizioni di gara possono essere evitate impiegando una sorta di meccanismo di blocco prima del codice che accede alla risorsa condivisa o all'esclusione reciproca.
Di seguito è riportato il programma modificato:
Esempio: problema relativo alle condizioni della gara risolto
#include <stdio.h>
#include <pthread.h>
int x= 0;
//Create mutex
pthread_mutex_t test_mutex;
void* fun(void* in)
{
int i;
for ( i = 0; i < 10000000; i++ )
{
//Lock mutex before going to change variable
pthread_mutex_lock(&test_mutex);
x++;
//Unlock mutex after changing the variable
pthread_mutex_unlock(&test_mutex);
}
}
int main()
{
pthread_t t1, t2;
printf("Point 1 >> X is: %d\n", x);
//Initlize mutex
pthread_mutex_init(&test_mutex, NULL);
pthread_create(&t1, NULL, fun, NULL);
pthread_create(&t2, NULL, fun, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
//Destroy mutex after use
pthread_mutex_destroy(&test_mutex);
printf("Point 2 >> X is: %d\n", x);
return 0;
}
Di seguito è riportato l'output:
Point 1 >> X is: 0
Point 2 >> X is: 20000000
Qui, la risposta arriva come 20.000.000 ogni volta.
Nota : il programma modificato, che è esente da errori di condizione di gara, richiederà molto tempo per essere eseguito. Perché c'è un sovraccarico sul blocco mutex e sblocco.