Internalpointers
30.07.2019, 14:54 Uhr
Lock-freies Multithreading mit atomaren Operationen
Ein Beitrag von Internalpointers.com erklärt das Synchronisieren von Threads mit Operationen, die direkt von der CPU ausgeführt werden und atomar erfolgen. Hier lesen Sie die Erklärung der Problemstellung, unten gibt's den Link zum englischen Artikel.
Das griechische Wort "Atom" bedeutet unzerlegbar. Eine Aufgabe, die von einem Computer ausgeführt wird, gilt als atomar, wenn sie nicht mehr teilbar ist: Sie kann nicht in kleinere Schritte zerlegt werden. Atomizität ist eine wichtige Eigenschaft von Multithread-Operationen: Da sie unteilbar sind, gibt es keine Möglichkeit, dass ein Thread durch eine atomare Operation gleitet, die gleichzeitig von einer anderen ausgeführt wird. Wenn beispielsweise ein Thread atomar auf gemeinsame Daten schreibt, kann kein anderer Thread die Änderung halbfertig lesen. Umgekehrt, wenn ein Thread atomar aus gemeinsamen Daten liest, sieht er den Wert so, wie er zu einem bestimmten Zeitpunkt erschienen ist. Mit anderen Worten, es besteht keine Gefahr von Datenrennen.
Synchronisations-Primitive werden unter anderem verwendet, um Operationen, die sich mit Daten befassen, die über mehrere Threads verteilt sind, Atomizität zu verleihen. Wie? Sie erlauben einfach einem einzelnen Thread, seine gleichzeitige Arbeit zu erledigen, während andere vom Betriebssystem blockiert werden, bis der erste abgeschlossen ist. Die Begründung ist, dass ein blockierter Thread anderen nicht schadet. Aufgrund ihrer Fähigkeit, Threads einzufrieren, werden solche Synchronisations-Primitive auch als Blockiermechanismen bezeichnet. Jeder Blockiermechanismus wird für die überwiegende Mehrheit Ihrer Anwendungen hervorragend funktionieren. Bei richtiger Anwendung sind sie schnell und zuverlässig. Sie führen jedoch einige Nachteile ein, die Sie vielleicht in Betracht ziehen sollten:
- Sie blockieren andere Threads – ein ruhender Thread wartet einfach auf das Wecksignal und tut nichts: Es könnte wertvolle Zeit verschwenden.
- Sie könnten Ihre Anwendung aufhängen – wenn ein Thread, der eine Sperre für eine primitive Synchronisation hält, aus irgendeinem Grund abstürzt, wird die Sperre selbst nie freigegeben und die wartenden Threads bleiben für immer stecken.
- Sie haben wenig Kontrolle darüber, welcher Thread schlafen wird – es liegt in der Regel am Betriebssystem, den zu blockierenden Thread auszuwählen. Dies kann zu einem unglücklichen Ereignis führen, das als Prioritätsumkehr bekannt ist: Ein Thread, der eine sehr wichtige Aufgabe ausführt, wird von einem anderen mit einer niedrigeren Priorität blockiert.
Meistens interessieren Sie sich nicht für diese Probleme, da sie die Korrektheit Ihrer Programme nicht beeinträchtigen. Andererseits ist es manchmal wünschenswert, Threads immer einsatzbereit zu haben, insbesondere wenn Sie die Vorteile von Multiprozessor-/Mehrkernhardware nutzen wollen. Oder vielleicht können Sie sich kein System leisten, das an einem toten Thread hängen bleiben könnte. Oder noch einmal, das Problem der Prioritätsinversion scheint zu gefährlich, um es zu ignorieren.
Lock-freie Programmierung zur Rettung Die gute Nachricht: Es gibt eine andere Möglichkeit, gleichzeitige Aufgaben in Ihrer Multithreading-App zu kontrollieren, um die oben genannten Punkte zu vermeiden. Bekannt als lock-free programming oder lockless programming, ist es eine Technik, um Änderungsdaten sicher zwischen mehreren Threads auszutauschen, ohne die Kosten für das Sperren und Entsperren. Die schlechte Nachricht: Das ist Low-Level-Material. Viel niedriger als die Verwendung der traditionellen Synchronisations-Primitive wie Mutexe und Semaphoren: Diesmal kommen wir dem Metall näher. Trotzdem ist die lockfreie Programmierung eine gute mentale Herausforderung und eine großartige Gelegenheit, besser zu verstehen, wie ein Computer tatsächlich funktioniert. Die blockierfreie Programmierung basiert auf atomaren Anweisungen, das heißt Operationen, die direkt von der CPU ausgeführt werden und atomar erfolgen.
Wie man das macht erklärt der englischsprachige Beitrag "Lock-free multithreading with atomic operations", den Sie hier lesen können.