Jetzt ist gewährleistet, dass mehrere Threads Elemente zur Warteschlange sicher hinzufügen oder aus ihr entfernen. Dennoch bleibt das Performanceproblem. Wenn ein Thread ein Element aus der Warteschlange entfernt, überprüft er laufend die Größe der Warteschlange. Das vergeudet wertvolle Prozessorzeit. Idealerweise sollte der Thread so lange ruhen, bis es etwas aus der Warteschlange zu entfernen gibt. Genau diesem Zweck dienen Bedingungsvariablen.
Ein Beispiel zur Verdeutlichung: Angenommen, Karin wartet darauf, dass Karl etwas zu essen kauft und es in den Kühlschrank packt. Sie geht zum Kühlschrank und öffnet ihn, um festzustellen, dass nichts zu essen da ist. Nun könnte sie sich entweder neben den Kühlschrank stellen und ihn andauernd auf- und zumachen, bis Karl es zwischendurch schafft, Essen hineinzupacken. Oder sie legt sich aufs Sofa und schläft so lange, bis Karl sie aufweckt, nachdem er etwas zu essen in den Kühlschrank gepackt hat. Karin und Karl sind hier die Threads und das Sofa ist eine Bedingungsvariable, auf der Karin ausruht, bis Karl ihr das Zeichen zum Aufwachen gibt.
Mithilfe von Bedingungsvariablen kann man Threads mitteilen, zu warten, bis ein anderer Thread sie aufweckt. Jede Bedingungsvariable ist mit einem Lock verknüpft. Wenn ein Thread auf eine Variable warten soll, wird das verknüpfte Lock freigegeben. Soll der Thread wieder aufwachen, wird der Lock zugewiesen. Häufig werden Bedingungsvariablen und Locks nach folgendem Muster verwendet:
Hier überprüfen die Threads eine Bedingung in foo(), ehe sie eine Aktion ausführen. Falls die Bedingung nicht wahr ist, wartet der Thread auf das entsprechende Signal und führt die Überprüfung dann durch. Während der Thread wartet, gibt er das Lock frei. Damit kann ein anderer Thread diesen in bar() erhalten, um den Status zu verändern. Nach der Statusänderung in bar() signalisiert der modifizierende Thread der Bedingungsvariable, einen wartenden Thread zu benachrichtigen, dass der Status sich geändert hat. Der wartende Thread wacht dann auf, übernimmt wieder das Lock und führt die Überprüfung der Bedingung erneut durch.
Das Warteschlangen-Beispiel wird nunmehr um Bedingungsvariablen ergänzt. Dadurch verschwendet die dequeue-Methode keine CPU-Zyklen in einer Endlosschleife, nur um die Größe der Warteschlange zu überprüfen.
Neueste Kommentare
Noch keine Kommentare zu Einführung in die Multithreading-Programmierung
Kommentar hinzufügenVielen Dank für Ihren Kommentar.
Ihr Kommentar wurde gespeichert und wartet auf Moderation.