- Busy-Waiting
-
Aktives Warten - auch busy waiting genannt - bezeichnet eine Aktivität eines Programms, mit der die Zeit bis zur Erfüllung einer Bedingung aktiv durch Ausführung von Anweisungen, welche den Zustand des Programms nicht verändern, überbrückt wird.
Inhaltsverzeichnis
Implementierung
Aktives Warten wird mittels wiederholt auszuführenden Anweisungen, mit denen geprüft wird, ob die Bedingung erfüllt ist, implementiert:
solange (Bedingung b nicht erfüllt) { tue nichts; }
Aktives Warten nutzt offensichtlich Prozessorkapazität für die sofortige, wiederholte Überprüfung, ob die Bedingung erfüllt ist. In seiner reinen Form werden außer der Überprüfung keine weiteren Aktionen ausgeführt. Es ist daher als verschwenderisch zu bezeichnen.
Anwendungen
Zeitüberbrückung
Aktives Warten kann eingesetzt werden, um eine Zeitspanne einer gegebenen Länge zu überbrücken. Die Länge der zu überbrückenden Zeitspanne wird unter Berücksichtigung der Ausführungsdauer einer Iteration der Schleife vom Programmierer in eine Anzahl zu durchlaufender Iterationen umgerechnet:
int i = 0; solange (i < num_iterationen) { i = i + 1; }
Synchronisation
Häufiger als zur Zeitüberbrückung wird aktives Warten zur Synchronisation der Aktivitäten parallel laufender/arbeitender Komponenten eines Rechensystems eingesetzt. Bei den Komponenten handelt es sich um Software-Komponenten (Prozesse bzw. Threads) oder um Software-Komponenten, die mit Hardware-Komponenten (Geräte) kooperieren. In Synchronisationssituationen wird die Reihenfolge, in der die Aktionen der Komponenten ausgeführt werden, geregelt, da eine beliebige parallele oder zeitlich verschränkte Ausführung der Aktionen unerwünscht ist (s. Prozesssynchronisation).
Gebräuchlich ist der Einsatz von aktivem Warten zur Synchronisation in folgenden Situationen:
- Zustandsabfrage
- Eine Komponente A (eine Software-Komponente) kann erst dann mit ihren Aktionen fortsetzen, wenn eine Komponente B (oftmals ein Gerät) einen bestimmten Zustand erreicht hat. Das Erreichen des Zustands in der Komponente B wird auf eine Weise angezeigt, die eine Prüfung durch die Komponente A zulässt (s. Memory Mapped I/O). Komponente A setzt dann aktives Warten ein, um zu verhindern, dass sie bereits Aktionen ausführt, obwohl dies der Zustand der Komponente B noch nicht zuläßt. Das aktive Warten wird dann auch polling genannt.
- Oft ist es ausreichend, die Zustandsabfrage nicht ununterbrochen vorzunehmen:
solange (Bedingung b nicht erfüllt) { warte für einige Zeit; }
- Diese Variante des aktiven Wartens wird auch als slow busy waiting oder lazy polling bezeichnet. Voraussetzung für einen nutzbringenden Einsatz ist jedoch, dass mit Hilfe eines Betriebssystems oder einer Laufzeitumgebung die freigewordene Prozessorkapazität genutzt wird, um ein anderes Programm vom Prozessor ausführen zu lassen. Nachteilig an der Variante ist neben der nach wie vor vorhandenen, wenn auch verringerten Verschwendung von Prozessorkapazität, dass oftmals länger als nötig gewartet wird, weil die Bedingung erst nach Ablauf der Wartezeit wieder geprüft wird.
- Abfrage einer Sperre
- Wird zur Synchronisation der Aktivitäten von Software-Komponenten (Prozessen bzw. Threads) speziell eine gemeinsam genutzte Variable vereinbart und wird mit einer Veränderung des Variablenwerts angezeigt, dass ein Prozess/Thread mit seinen Aktionen fortsetzen kann, so verwendet der Prozess/Thread aktives Warten, um die Veränderung zu erkennen:
Gemeinsam von A und B genutzte Variable: lock Interpretation des Werts: 0 gesperrt, ungleich 0 offen Initialisierung: lock = 0 Prozess A Prozess B ... ... solange (lock == 0) { ... ; lock = 1; } ... Aktion a ...
- Da die Variable lock verhindert, dass der Prozess/Thread A die Aktion a unkontrolliert durch B fortsetzt, wird die Variable Sperrvariable (Lock) genannt. Da die Veränderung der Variable mittels wiederholtes (drehendes) Abfragen festgestellt wird, spricht man auch von einem Spinlock. Spinlocks sind ein grundlegendes Konzept der Prozesssynchronisation.
Wikimedia Foundation.