Suche…


Einführung

Beim Schreiben von Multithread-Anwendungen sind Race-Bedingungen eines der häufigsten Probleme. Also dokumentieren wir die Wie erkennen Sie sie? und wie gehst du damit um?

Beispiel: Betrachten Sie zwei Threads T1 und T2.

Wie entdeckst du sie?

Wenn auf dieselbe Variable / Ressource / Speicherposition von mehreren Threads zugegriffen werden kann und mindestens der Thread den Wert von Variable / Ressource / Speicherposition ändert, kann die Race Condition auftreten . Wenn ein Thread den Wert von variable / resource / memory ändert und ein anderer Thread versucht, denselben zu lesen, erhält er nicht den aktualisierten Wert.

Hinweis : Wenn alle Threads nur die Variable / Ressource / Speicherposition lesen, tritt keine Race Condition auf.

Beispiel: Programm leidet unter Race Condition

#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;
}

Die Ausgabe auf meinem Bildschirm ist:

Point 1 >> X is: 0
Point 2 >> X is: 9925047

Ihre Ausgabe wird variieren. Aber es wird sicher nicht 20.000.000 sein. Da beide Threads dieselbe Schleife ausführen und die globale Variable int x;

for ( i = 0; i < 10000000; i++ )
{
   x++; 
}

Der Endwert von x in Zeile Point 2 >> X is: 9925047 sollte 20.000.000 sein. Ist aber nicht so.

Der Status von x kann von einem anderen Thread geändert werden, während zwischen x gelesen und zurückgeschrieben wird.

Angenommen, ein Thread ruft den Wert von x ab, hat ihn jedoch noch nicht gespeichert. Ein anderer Thread kann auch denselben Wert von x abrufen (da er noch nicht geändert wurde), und dann würden beide denselben Wert (x + 1) in x speichern.

Beispiel:

Thread 1: liest x, Wert ist 7

Thread 1: addiere 1 zu x, der Wert ist jetzt 8

Thread 2: liest x, Wert ist 7

Thread 1: speichert 8 in x

Thread 2: fügt 1 zu x hinzu, der Wert ist jetzt 8

Thread 2: speichert 8 in x

Wie gehst du damit um?

Rennbedingungen können vermieden werden, indem ein Sperrmechanismus vor dem Code verwendet wird, der auf die gemeinsam genutzte Ressource zugreift, oder ein gegenseitiger Ausschluss.

Folgendes ist ein modifiziertes Programm:

Beispiel: Race Condition Problem behoben

#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;
}

Folgendes ist die Ausgabe:

Point 1 >> X is: 0
Point 2 >> X is: 20000000

Hier lautet die Antwort jedes Mal 20.000.000.

Hinweis : Ein geändertes Programm, das frei von Race-Race-Fehlern ist, benötigt viel Zeit für die Ausführung. Denn es gibt eine Überlastung beim mutex Sperren und Entsperren.



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow