pthreads
Condition de course dans les pthreads
Recherche…
Introduction
Exemple: Consider aura deux threads T1 et T2.
Comment les détectez-vous?
Si la même variable / ressource / emplacement mémoire est accessible par plusieurs threads et qu'au moins le thread modifie la valeur de la variable / ressource / emplacement mémoire , alors une situation de concurrence peut survenir. Parce que si un thread modifie la valeur de la variable / ressource / emplacement mémoire et qu'un autre thread essaie de lire la même chose, il n'obtiendra pas la valeur mise à jour.
Remarque : Si tous les threads ne font que lire la variable / ressource / emplacement mémoire, alors la condition de concurrence ne se produira pas.
Exemple: le programme souffre d'une condition de course
#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;
}
La sortie sur mon écran est la suivante:
Point 1 >> X is: 0
Point 2 >> X is: 9925047
Votre sortie variera. Mais à coup sûr, ce ne sera pas 20 000 000. Comme les deux threads exécutent la même boucle et ont la variable globale int x;
for ( i = 0; i < 10000000; i++ )
{
x++;
}
Donc, la valeur finale de x dans la ligne Point 2 >> X is: 9925047 devrait être Point 2 >> X is: 9925047 . Mais ce n'est pas le cas.
L'état de x peut être modifié par un autre thread pendant le temps écoulé entre la lecture de x et la réécriture.
Disons qu'un thread récupère la valeur de x, mais ne l'a pas encore stockée. Un autre thread peut également récupérer la même valeur de x (car aucun thread n'a encore changé) et ensuite ils stockeront tous les deux la même valeur (x + 1) dans x!
Exemple:
Thread 1: lit x, la valeur est 7
Fil 1: ajouter 1 à x, la valeur est maintenant 8
Thread 2: lit x, la valeur est 7
Fil 1: stocke 8 en x
Thread 2: ajoute 1 à x, la valeur est maintenant 8
Fil 2: stocke 8 en x
Comment les manipulez-vous?
Les conditions de course peuvent être évitées en utilisant une sorte de mécanisme de verrouillage avant le code qui accède à la ressource partagée ou une exclusion mutuelle.
Le programme suivant est modifié:
Exemple: problème de condition de course résolu
#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;
}
Voici le résultat:
Point 1 >> X is: 0
Point 2 >> X is: 20000000
Ici, la réponse est 20 000 000 à chaque fois.
Remarque : le programme modifié, qui ne contient aucune erreur de condition de course, prendra beaucoup de temps à exécuter. Parce que le mutex verrouille et déverrouille.