Eine "Race-Bedingung" liegt vor, wenn Multithread-Code (oder auf andere Weise paralleler Code), der auf eine gemeinsam genutzte Ressource zugreifen würde, dies so tun könnte, dass unerwartete Ergebnisse erzielt werden.
Nehmen Sie dieses Beispiel:
for ( int i = 0; i < 10000000; i++ )
{
x = x + 1;
}
Wenn Sie 5 Threads hätten, die diesen Code gleichzeitig ausführen, würde der Wert von x NICHT 50.000.000 betragen. Es würde in der Tat mit jedem Lauf variieren.
Dies liegt daran, dass jeder Thread, um den Wert von x zu erhöhen, Folgendes tun muss: (offensichtlich vereinfacht)
Rufen Sie den Wert von x ab
Addiere 1 zu diesem Wert
Speichern Sie diesen Wert in x
Jeder Thread kann sich zu jedem Zeitpunkt in einem beliebigen Schritt in diesem Prozess befinden, und sie können aufeinander treten, wenn eine gemeinsam genutzte Ressource beteiligt ist. Der Status von x kann von einem anderen Thread während der Zeit zwischen dem Lesen von x und dem Zurückschreiben geändert werden.
Angenommen, ein Thread ruft den Wert von x ab, hat ihn jedoch noch nicht gespeichert. Ein anderer Thread kann auch den gleichen Wert von x abrufen (da noch kein Thread ihn geändert hat), und dann würden beide den gleichen Wert (x + 1) wieder 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: addiert 1 zu x, der Wert ist jetzt 8
Thread 2: speichert 8 in x
Rennbedingungen können vermieden werden, indem vor dem Code, der auf die gemeinsam genutzte Ressource zugreift, eine Art Sperrmechanismus verwendet wird:
for ( int i = 0; i < 10000000; i++ )
{
//lock x
x = x + 1;
//unlock x
}
Hier lautet die Antwort jedes Mal 50.000.000.
Weitere Informationen zum Sperren finden Sie unter: Mutex, Semaphor, kritischer Abschnitt, freigegebene Ressource.