Asynchrone Programmierung in C++: Vollständiger Leitfaden

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

Asynchrones Programmieren in C++: Eine vollständige Anleitung



Moderne Anwendungen erfordern hohe Leistung und Reaktionsfähigkeit. Asynchrones Programmieren in C++ ermöglicht die Ausführung langwieriger Operationen (E/A, Netzwerkanfragen, komplexe Berechnungen), ohne den Hauptthread zu blockieren. In dieser Anleitung werden wir die wichtigsten C++-Mechanismen für asynchrone Arbeit behandeln: von klassischen std::thread und std::async bis hin zu modernen C++20-Koroutinen. Sie erfahren, wie Sie effizienten und sicheren asynchronen Code schreiben.



1. Grundlagen: std::thread und std::async



Beginnen wir mit den grundlegenden Werkzeugen. std::thread erstellt einen neuen Ausführungsthread, erfordert jedoch manuelle Verwaltung und Synchronisation. Eine bequemere Option ist std::async, das eine Funktion asynchron startet und ein std::future zum Abrufen des Ergebnisses zurückgibt.



#include <iostream>#include <future>#include <chrono>

int long_running_task(int input) { std::this_thread::sleep_for(std::chrono::seconds(2)); return input * 10;}

int main() { std::cout << "Starte asynchrone Aufgabe..."; std::future<int> result = std::async(std::launch::async, long_running_task, 5); // Etwas Nützliches tun, während die Aufgabe läuft std::cout << "Hauptthread arbeitet weiter..."; // Ergebnis abrufen (blockiert, falls die Aufgabe noch nicht abgeschlossen ist) int value = result.get(); std::cout << "Ergebnis: " << value << std::endl; return 0;}


Wichtige Punkte:

  • std::launch::async — garantiert den Start in einem separaten Thread.
  • std::launch::deferred — verzögert die Ausführung bis zum Aufruf von get().
  • Die Methode get() blockiert den Thread, bis das Ergebnis vorliegt.


2. Fortgeschrittene Arbeit: std::promise und std::future



Wenn Sie ein Ergebnis von einem Thread an einen anderen übergeben müssen, verwenden Sie das Paar std::promise und std::future. promise setzt den Wert, und future empfängt ihn. Dies ist besonders nützlich beim Thread-Pooling oder bei Aufgabenketten.



#include <iostream>#include <future>#include <thread>

void worker(std::promise<int> prom) { try { int result = 42; // Komplexe Berechnungen prom.set_value(result); } catch (...) { prom.set_exception(std::current_exception()); }}

int main() { std::promise<int> prom; std::future<int> fut = prom.get_future(); std::thread t(worker, std::move(prom)); // Ergebnis abrufen int value = fut.get(); std::cout << "Wert empfangen: " << value << std::endl; t.join(); return 0;}


Wichtige Besonderheiten:

  • promise kann nicht kopiert, sondern nur verschoben werden.
  • Ausnahmen werden über set_exception übergeben.
  • future kann nur einmal verwendet werden (einmaliger Abruf).


3. C++20-Koroutinen: Moderner Ansatz



Koroutinen (coroutines) sind ein leistungsstarkes Werkzeug, das in C++20 hinzugefügt wurde. Sie ermöglichen es, die Ausführung einer Funktion zu unterbrechen und wieder aufzunehmen, ohne den Thread zu blockieren. Dies ist ideal für asynchrone E/A-Operationen und Generatoren.



#include <iostream>#include <coroutine>#include <future>

struct SimpleTask { struct promise_type { SimpleTask get_return_object() { return {}; } std::suspend_never initial_suspend() { return {}; } std::suspend_never final_suspend() noexcept { return {}; } void return_void() {} void unhandled_exception() { std::exit(1); } };};

SimpleTask async_operation() { std::cout << "Start der Koroutine";

Blogs

Buchempfehlungen