Blog 5 Min. Lesezeit

C++-Concurrency meistern mit „Concurrency with Modern C++“

Diesen Artikel teilen
Master C++ Concurrency with 'Concurrency with Modern C++

C++11 und die nachfolgenden Standards führten eine neue Threading-Bibliothek ein. Sie enthält Hilfsmittel zum Starten und Verwalten von Threads sowie Synchronisationsprimitive wie Mutexe und andere Sperren, atomare Variablen und weitere zugehörige Werkzeuge.

Eine standardisierte Möglichkeit, Nebenläufigkeit in C++ zu verwalten, ist ein großer Fortschritt. Vor Einführung dieser Funktionen waren C++-Projekte auf unterschiedliche Bibliotheken und Ansätze angewiesen, um Concurrency zu handhaben.

In diesem Beitrag betrachten wir die Vorteile der Lektüre des Buches „Concurrency with Modern C++“ von Rainer Grimm.

Pragmatischer Ansatz

In der Informatik sind manche Bücher vor allem akademisch ausgerichtet und richten sich an Studierende, während andere für Entwickler geschrieben sind, die praktische Anleitungen zur Lösung realer Probleme bei der Produktentwicklung benötigen. Dieses Buch verfolgt einen pragmatischen Ansatz: Gleich zu Beginn verweist es auf das Paket mit den Beispielen und erklärt, wie diese kompiliert werden. Ziel ist es, jede im Buch vorgestellte Lösung praktisch nachzuvollziehen.

Von Anfang an das Gesamtbild

Normalerweise verschaffen Inhaltsverzeichnis und Einleitung einen ersten Eindruck vom Inhalt eines Buches. Häufig reicht das jedoch nicht aus, um seine Ziele wirklich klar zu erfassen.

Interessant ist der achtseitige Abschnitt „Quick Overview“, der das Problem, die Lösungsansätze und die von den neuen Standards bereitgestellten Funktionen klar erläutert.

Das Speichermodell verständlich erklärt

Bereits im „Quick Overview“ werden die Rahmenbedingungen des Speichermodells verständlich erklärt.

Die Grundlage von Multithreading ist ein klar definiertes Speichermodell. Dieses muss unter anderem folgende Aspekte abdecken: • Atomare Operationen: Operationen, die ohne Unterbrechung ausgeführt werden können. • Partielle Ordnung von Operationen: Abfolgen von Operationen, deren Reihenfolge nicht verändert werden darf. • Sichtbare Auswirkungen von Operationen: Garantien dafür, wann Operationen auf gemeinsam genutzten Variablen in anderen Threads sichtbar werden.

Im Abschnitt zum Speichermodell liefert der Autor eine tiefgehende Analyse der Speicherbedingungen und ergänzt sie durch zahlreiche Codebeispiele, die das Verständnis des Speicherverhaltens in nebenläufigen Szenarien erleichtern. Besonders hilfreich sind die Abbildungen, mit denen Probleme und ihre Lösungen veranschaulicht werden.

Dieser Abschnitt stellt außerdem die Funktionen vor, die neuere Standards für den Umgang mit Speicher in nebenläufigen Programmen bereitstellen.

Multithreading verständlich gemacht

Zu viele Entwickler von Multithreading-Programmen lernen zunächst, mehrere Threads zu erzeugen und irgendwie zum Laufen zu bringen. Doch dann geraten die Threads außer Kontrolle und der Entwickler weiß nicht mehr weiter. Fehler zu beheben oder neuen Code hinzuzufügen wird anschließend schnell zur Qual. Mitunter erzeugt die Behebung eines Fehlers gleich mehrere neue.

Daher empfiehlt es sich, die Grundlagen des Multithreadings zu beherrschen, bevor es in Produktivcode eingesetzt wird. Glücklicherweise verfügt C++ seit C++11 über eine Multithreading-Schnittstelle, die alle grundlegenden Bausteine für die Entwicklung von Multithreading-Programmen bietet. Ein standardisierter Umgang mit Threads ist eindeutig von Vorteil.

Eine Stärke des Multithreading-Abschnitts ist sein schrittweiser Aufbau. Dadurch eignet er sich auch für Einsteiger, die noch nicht mit Threads vertraut sind. Ich würde diesen Abschnitt ebenso erfahrenen C++-Entwicklern empfehlen. Obwohl ich selbst seit vielen Jahren mit Threads arbeite, habe ich dort mehrere interessante Details und neue Funktionen entdeckt.

Wie schon im Abschnitt zum Speichermodell erleichtern zahlreiche Codebeispiele und Abbildungen das Verständnis der Multithreading-Konzepte.

Fallstudien, um die Theorie praktisch anzuwenden

Nach der theoretischen Einführung in das Speichermodell und die Multithreading-Schnittstelle wendet der Autor das Gelernte praktisch an und liefert dazu einige Leistungskennzahlen.

Die Fallstudien sind leicht nachzuvollziehen, etwa das Beispiel zur Berechnung der Summe eines Vektors. Der Autor erläutert zudem ausführlich die verschiedenen Implementierungsvarianten, die moderne C++-Funktionen ermöglichen.

Nachdem Sie die erste Fallstudie gelesen und selbst nachvollzogen haben, verfügen Sie über ein praktisches Verständnis vieler Concurrency-Probleme und wissen, wie sie sich lösen lassen. Ich empfehle diese Fallstudie jedem Entwickler, der Nebenläufigkeit in C++ beherrschen möchte.

Herausforderungen und Best Practices zum Abschluss

Nachdem Speichermodell und Multithreading behandelt und anhand von Fallstudien vertieft wurden, stellt der Autor mehrere interessante Herausforderungen vor. Seine Motivation dafür beschreibt er wie folgt:

Nebenläufig zu programmieren ist von Natur aus kompliziert. Das gilt insbesondere bei der Verwendung von Funktionen aus C++11 und C++14. Dabei habe ich noch nicht einmal über das Speichermodell gesprochen. Ich hoffe, dass ein ganzes Kapitel über die Herausforderungen der nebenläufigen Programmierung Ihr Bewusstsein für die möglichen Fallstricke schärft.

Der Autor gibt außerdem mehrere Best Practices für den Umgang mit Concurrency und erklärt dazu:

Dieses Kapitel bietet Ihnen einen einfachen Satz von Regeln, um klar definierte und schnelle nebenläufige Programme in modernem C++ zu schreiben. Multithreading und insbesondere Parallelität und Concurrency sind in C++ noch relativ junge Themen. Daher werden in den kommenden Jahren weitere Best Practices entstehen. Betrachten Sie die Regeln dieses Kapitels nicht als vollständige Liste, sondern als notwendigen Ausgangspunkt, der sich mit der Zeit weiterentwickeln wird.

Fazit

Beim Lesen wird deutlich, dass der Autor ein Entwickler mit umfangreicher Erfahrung bei der Lösung realer Probleme in C++-Projekten ist. Das erklärt den pragmatischen Ansatz des Buches. Wir empfehlen es jedem Entwickler, der Concurrency in modernem C++ meistern möchte.

Diesen Artikel teilen