1328 Stimmen

Was ist eine Rennbedingung?

Beim Schreiben von Multithreading-Anwendungen ist eines der häufigsten Probleme die Race Condition.

Meine Fragen an die Gemeinschaft lauten:

  • Was ist die Rennbedingung?
  • Wie kann man sie erkennen?
  • Wie gehen Sie mit ihnen um?
  • Und schließlich: Wie kann man verhindern, dass sie auftreten?

10 Stimmen

Ich möchte darauf hinweisen, dass - ohne Angabe der Sprache - die meisten Teile dieser Frage nicht richtig beantwortet werden können, da die Definition, die Folgen und die Instrumente zu ihrer Verhinderung in den verschiedenen Sprachen unterschiedlich sein können.

0 Stimmen

@MikeMB. Einverstanden, außer bei der Analyse der Ausführung von Bytecode, wie sie von Race Catcher durchgeführt wird (siehe diesen Thread stackoverflow.com/a/29361427/1363844 ) können wir all die etwa 62 Sprachen ansprechen, die sich zu Bytecode kompilieren lassen (siehe de.wikipedia.org/wiki/Liste_der_JVM_Sprachen )

47voto

Chris Conway Punkte 54023

Eine gewissermaßen kanonische Definition lautet: " wenn zwei Threads gleichzeitig auf denselben Speicherplatz zugreifen und mindestens einer der Zugriffe ein Schreibzugriff ist ." In diesem Fall kann der "lesende" Thread den alten oder den neuen Wert erhalten, je nachdem, welcher Thread "das Rennen gewinnt". Das ist nicht immer ein Fehler - einige wirklich haarige Low-Level-Algorithmen machen das sogar absichtlich - aber es sollte generell vermieden werden. @Steve Gury gibt ein gutes Beispiel dafür, wann dies ein Problem sein könnte.

3 Stimmen

Könnten Sie bitte ein Beispiel dafür nennen, wie Race Conditions nützlich sein können? Googeln hat nicht geholfen.

3 Stimmen

@Alex V. Zu diesem Zeitpunkt habe ich keine Ahnung, wovon ich gesprochen habe. Ich glaube, das war eine Anspielung auf die sperrfreie Programmierung, aber es ist nicht ganz richtig zu sagen, dass diese von Race Conditions abhängt.

40voto

Steve Gury Punkte 14228

Eine Race Condition ist eine Art von Fehler, der nur unter bestimmten zeitlichen Bedingungen auftritt.

Beispiel: Stellen Sie sich vor, Sie haben zwei Threads, A und B.

In Thema A:

if( object.a != 0 )
    object.avg = total / object.a

In Thema B:

object.a = 0

Wenn Thread A kurz nach der Überprüfung, dass object.a nicht null ist, unterbrochen wird, wird B Folgendes tun a = 0 und wenn Thread A den Prozessor übernimmt, wird er eine "Division durch Null" durchführen.

Dieser Fehler tritt nur dann auf, wenn Thread A direkt nach der if-Anweisung preempted wird; dies ist sehr selten, kann aber vorkommen.

32voto

nybon Punkte 7875

Race Condition ist nicht nur mit Software, sondern auch mit Hardware verbunden. Eigentlich wurde der Begriff ursprünglich von der Hardware-Industrie geprägt.

Según wikipedia :

Der Begriff geht auf die Idee zurück, dass zwei Signale, die sich gegenseitig überholen zu zuerst den Output beeinflussen .

Wettlaufbedingung in einer logischen Schaltung:

enter image description here

Die Softwareindustrie hat diesen Begriff unverändert übernommen, was ihn ein wenig schwer verständlich macht.

Sie müssen einige Ersetzungen vornehmen, um sie in der Softwarewelt abzubilden:

  • "zwei Signale" => "zwei Threads"/"zwei Prozesse"
  • "Einfluss auf den Output" => "Einfluss auf einen gemeinsamen Zustand"

In der Softwarebranche bedeutet Race Condition also, dass zwei Threads"/"zwei Prozesse" gegeneinander antreten, um "einen gemeinsamen Zustand zu beeinflussen", und dass das Endergebnis des gemeinsamen Zustands von einem subtilen Zeitunterschied abhängt, der durch eine bestimmte Thread-/Prozess-Startreihenfolge, Thread-/Prozessplanung usw. verursacht werden könnte.

20voto

tsellon Punkte 2356

Race Conditions treten in Multi-Thread-Anwendungen oder Multiprozesssystemen auf. Eine Race Condition ist im Grunde alles, was davon ausgeht, dass zwei Dinge, die sich nicht im selben Thread oder Prozess befinden, in einer bestimmten Reihenfolge ablaufen, ohne dass Maßnahmen ergriffen werden, um sicherzustellen, dass dies der Fall ist. Dies geschieht häufig, wenn zwei Threads Nachrichten weitergeben, indem sie Mitgliedsvariablen einer Klasse setzen und überprüfen, auf die beide zugreifen können. Es gibt fast immer eine Wettlaufsituation, wenn ein Thread sleep aufruft, um einem anderen Thread Zeit zu geben, eine Aufgabe zu beenden (es sei denn, dieser sleep befindet sich in einer Schleife mit einem Prüfmechanismus).

Werkzeuge zur Verhinderung von Wettlaufsituationen sind von der Sprache und dem Betriebssystem abhängig, aber einige gängige sind Mutexe, kritische Abschnitte und Signale. Mutexe sind gut, wenn Sie sicherstellen wollen, dass Sie der Einzige sind, der etwas tut. Signale sind gut, wenn Sie sicherstellen wollen, dass jemand anderes etwas zu Ende gebracht hat. Eine Minimierung der gemeinsam genutzten Ressourcen kann auch dazu beitragen, unerwartetes Verhalten zu verhindern

Die Erkennung von Rennbedingungen kann schwierig sein, aber es gibt einige Anzeichen. Code, der sich stark auf Schlafphasen stützt, ist anfällig für Race Conditions, also prüfen Sie zunächst, ob der betroffene Code Aufrufe zum Schlafen enthält. Das Hinzufügen besonders langer Schlafphasen kann auch zur Fehlersuche verwendet werden, um eine bestimmte Reihenfolge von Ereignissen zu erzwingen. Dies kann nützlich sein, um das Verhalten zu reproduzieren und zu sehen, ob man es durch Änderung des Timings zum Verschwinden bringen kann, und um eingeführte Lösungen zu testen. Nach der Fehlersuche sollten die Schlafphasen wieder entfernt werden.

Ein Anzeichen für eine Wettlaufbedingung ist jedoch, wenn ein Problem nur auf einigen Rechnern sporadisch auftritt. Häufige Fehler sind Abstürze und Deadlocks. Mit Hilfe der Protokollierung sollten Sie in der Lage sein, den betroffenen Bereich zu finden und von dort aus weiterzuarbeiten.

12voto

Konstantin Dinev Punkte 32517

Microsoft hat einen sehr detaillierten Bericht veröffentlicht Artikel zu dieser Frage der Race Conditions und Deadlocks. Der am besten zusammengefasste Auszug daraus wäre der Titelabsatz:

Eine Wettlaufbedingung tritt auf, wenn zwei Threads auf eine gemeinsame Variable zum Zeitpunkt zur gleichen Zeit zugreifen. Der erste Thread liest die Variable, und der zweite Thread liest denselben Wert aus der Variablen. Dann führen der erste Thread und der zweite Thread ihre Operationen mit dem Wert und wetteifern um zu sehen, welcher Thread den Wert zuletzt in die gemeinsame Variable schreiben kann. Der Wert des Threads, der seinen Wert zuletzt schreibt, bleibt erhalten, weil der Thread über den Wert schreibt, den der vorherige Thread geschrieben hat.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X