Ricerca…


introduzione

Quando si scrivono applicazioni multi-thread, uno dei problemi più comuni riscontrati sono le condizioni di gara. Quindi documentiamo come li rilevi? e come li gestisci?

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.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow