Reaktive Programmierung in C++: Bibliotheken RxCpp und Boost.Signals2

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Reaktive Programmierung in C++: Überblick über die Bibliotheken RxCpp und Boost.Signals2



Reaktive Programmierung (Reactive Programming) ist ein Paradigma, das auf asynchrone Datenströme und die Weitergabe von Änderungen ausgerichtet ist. In C++ wird dieses Paradigma durch Bibliotheken umgesetzt, die es ermöglichen, Ereignisse, Signale und asynchrone Datensequenzen auf deklarative Weise zu verarbeiten. In diesem Artikel betrachten wir zwei Schlüsselbibliotheken für die reaktive Programmierung in C++: RxCpp (Reactive Extensions for C++) und Boost.Signals2. Beide Bibliotheken lösen die Aufgabe der Ereignisverarbeitung, jedoch mit unterschiedlichem Komplexitätsgrad und Funktionsumfang.



Warum ist reaktive Programmierung in C++ notwendig?



Traditioneller imperativer Code erweist sich oft als komplex bei der Arbeit mit asynchronen Ereignissen, Benutzereingaben, Netzwerkanfragen oder Multithreading. Reaktive Programmierung bietet:



  • Deklarativer Ansatz: Sie beschreiben "was" passieren soll, nicht "wie".
  • Komposition von Strömen: Einfaches Kombinieren, Filtern und Transformieren von Datenströmen.
  • Multithreading-Verwaltung: Integrierte Mechanismen zum Kontextwechsel und zur Synchronisation.
  • Fehlerbehandlung: Eine einheitliche Pipeline für Daten und Ausnahmen.


Die Bibliothek RxCpp



RxCpp ist ein Port der Reactive Extensions (Rx) für C++. Sie bietet einen leistungsstarken Satz von Operatoren für die Arbeit mit asynchronen Datensequenzen. Die grundlegenden Konzepte sind: observable (Datenquelle) und observer (Abonnent).



Installation

RxCpp ist eine Header-Only-Bibliothek. Es reicht aus, das Repository zu klonen und die Header-Dateien einzubinden:

#include <rxcpp/rx.hpp>using namespace rxcpp;using namespace rxcpp::sources;using namespace rxcpp::operators;


Beispiel 1: Einfaches Abonnieren eines Zahlenstroms

Erstellen wir ein observable, das die Zahlen von 1 bis 5 generiert, und abonnieren es:

#include <iostream>#include <rxcpp/rx.hpp>

int main() { auto values = range(1, 5); // observable: 1,2,3,4,5

values. subscribe([](int v) { std::cout << "Received: " << v << std::endl; }, []() { std::cout << "Stream completed" << std::endl; });

return 0;}


Beispiel 2: Filtern und Transformieren

Reaktive Operatoren ermöglichen eine einfache Datenmanipulation. Filtern wir gerade Zahlen und multiplizieren sie mit 10:

auto values = range(1, 10);

values .filter([](int v) { return v % 2 == 0; }) // nur gerade .map([](int v) { return v * 10; }) // mit 10 multiplizieren .subscribe([](int v) { std::cout << "Result: " << v << std::endl; });// Ausgabe: 20, 40, 60, 80, 100


Beispiel 3: Zusammenführen von Strömen

Führen wir zwei Ströme mit dem Operator merge zusammen:

auto stream1 = interval(std::chrono::milliseconds(100)).take(3);auto stream2 = interval(std::chrono::milliseconds(150)).take(3);

stream1.merge(stream2) .subscribe([](long v) { std::cout << v << " "; });// Mögliche Ausgabe: 0 0 1 2 1 2 (Reihenfolge kann abweichen)


Die Bibliothek Boost.Signals2



Boost.Signals2 ist eine Bibliothek zur Implementierung von Signalen und Slots (signals & slots). Sie ist Teil der Boost-Bibliotheken und bietet einen typsicheren Mechanismus für Rückrufe. Im Gegensatz zu RxCpp ist Signals2 nicht für die Arbeit mit Datenströmen konzipiert, sondern eher für die Verarbeitung diskreter Ereignisse.



Grundlegende Konzepte

  • Signal (signal): Ein Objekt, das "ausgelöst" werden kann und alle seine Abonnenten benachrichtigt.
  • Slot (slot): Eine Funktion oder ein funktionales O

Empfehlungen