Spinlock
Ein Spinlock (Spin-Lock) ist ein Mechanismus zur Prozesssynchronisation. Es ist eine Sperre (Lock) zum Schutz einer gemeinsam genutzten Ressource durch konkurrierende Prozesse bzw. Threads (siehe Kritischer Abschnitt) nach dem Prinzip des wechselseitigen Ausschlusses (Mutex).
Implementierung
BearbeitenDie Sperre wird umgesetzt mittels aktiven Wartens:
// Eintrittsprotokoll solange (Sperrvariable besitzt Wert 'gesperrt') { // \ tue nichts; // | Achtung! Hier: } // | Atomares Vergleichen und Setzen setze Sperrvariable auf 'gesperrt' // / // Kritischer Abschnitt modifiziere Ressource // Austrittsprotokoll setze Sperrvariable auf 'frei'
Zu Anfang besitzt die Sperrvariable den Wert frei. Alle Prozesse durchlaufen für den Eintritt in einen kritischen Abschnitt das gleiche Protokoll: Wenn die Sperrvariable frei ist, setze sie auf gesperrt, ansonsten prüfe dies erneut (aktives Warten). Das Prüfen und Setzen erfolgt atomar und wird je nach Prozessorarchitektur unterschiedlich implementiert (siehe Fetch-and-add, Compare-and-swap oder Test-and-set).
Der Prozess, der die Sperrvariable auf gesperrt setzt, wird als „Besitzer“ der Sperrvariablen bezeichnet.
Vorteile
BearbeitenDas Verfahren vermeidet Kontextwechsel, die sehr zeitaufwändig sind. Wenn das Warten auf die Freigabe einer Sperre im Mittel kürzer als ein Kontextwechsel ist, dann sind Spinlocks trotz ihrer zusätzlichen Laufzeit schneller als alternative Mutexe. Dies erhöht die effektive Parallelität gegenüber threadwechselnden Synchronisationsmechanismen teilweise erheblich und ist daher bei stark nebenläufigen Algorithmen eine häufig anzutreffende Vorgehensweise (z. B. im Linux-Kernel[1]).
Nachteile
BearbeitenDas aktive Warten benötigt Laufzeit. Ein Spinlock kann die Programmausführung stark verlangsamen, wenn mehr Threads als Prozessorkerne vorhanden sind.
In Abhängigkeit vom Schedulingverfahren kann der Einsatz von Spinlocks auch zu Deadlocks führen. Dies resultiert aus dem Umstand, dass durch einen Spinlock der aktive Thread nicht suspendiert wird, sondern aktiv auf die Sperrvariable wartet (also ablaufend bleibt) und dadurch andere ablaufbereite Threads behindert. Folgendes Beispiel verdeutlicht das Problem: In einem Einprozessorsystem mit zwei Threads wird ein Spinlock von einem Thread L mit geringer Priorität erfolgreich gesperrt. Kurz darauf (und vor der Freigabe des Spinlocks durch Thread L) wird ein Thread H mit hoher Priorität durch ein Ereignis lauffähig und vom Scheduler aktiviert. Thread H versucht nun ebenfalls, den Spinlock zu sperren, und gerät dadurch in das aktive Warten. Bei einem Schedulingverfahren ohne Time Slicing entsteht dadurch ein Deadlock, da Thread L nicht wieder lauffähig wird und den Spinlock nicht mehr freigeben kann. Die Verwendung eines Synchronisationsmechanismus mit Threadwechsel hätte in diesem Beispiel den Deadlock verhindert.
Literatur
Bearbeiten- Sándor Juhász, Ákos Dudás, Tamás Schrádi: Cost of mutual exclusion with spin locks on multi-core CPUs. In: Proceedings of the 5th WSEAS congress on Applied Computing conference, and Proceedings of the 1st international conference on Biologically Inspired Computation (= BICA’12). World Scientific and Engineering Academy and Society (WSEAS), Stevens Point WI 2012, ISBN 978-1-61804-089-3, S. 15–19 (acm.org – Conference Paper).
- Mordechai Ben-Ari: Principles of Concurrent and Distributed Programming: Algorithms and Models (= Prentice-Hall International Series in Computer Science). 2. Auflage. Addison-Wesley, 2005, ISBN 978-0-321-31283-9.
- James H. Anderson, Yong-Jik Kim, Ted Herman: Shared-memory mutual exclusion: major research trends since 1986. In: Distrib. Comput. Band 16, Nr. 2–3. Springer-Verlag, September 2003, ISSN 0178-2770, S. 75–110, doi:10.1007/s00446-003-0088-6.
- M. Raynal, D. Beeson: Algorithms for mutual exclusion. MIT Press, Cambridge MA 1986, ISBN 0-262-18119-3.
Einzelnachweise
Bearbeiten- ↑ Lesson 1: Spin locks. In: The Linux Kernel Archives. Page maintained by Rob Landley, rob at landley dot net, 12. August 2013, abgerufen am 4. November 2013.