Aufgabenwarteschlangen für C++: vom Einfachen zum Komplexen
Eine Aufgabenwarteschlange (Task Queue) ist eines der Schlüsselmuster der Multithread-Programmierung. Sie ermöglicht die Organisation asynchroner Arbeitsausführung: Ein oder mehrere Produzenten-Threads fügen Aufgaben hinzu, während ein Pool von Arbeiter-Threads diese verarbeitet. In C++ gibt es dafür sowohl Standardmittel als auch spezialisierte Bibliotheken.
1. Standard-Warteschlange: std::queue mit Sperren
Die einfachste Variante ist die Verwendung von std::queue in Kombination mit einem Mutex und einer Bedingungsvariablen. Dies eignet sich für kleinere Projekte, bei denen der Synchronisierungsaufwand nicht kritisch ist.
#include <queue>#include <mutex>#include <condition_variable>
template<typename T>class ThreadSafeQueue { std::queue<T> q_; mutable std::mutex mtx_; std::condition_variable cv_;public: void push(T value) { std::lock_guard<std::mutex> lock(mtx_); q_.push(std::move(value)); cv_.notify_one(); }
T pop() { std::unique_lock<std::mutex> lock(mtx_); cv_.wait(lock, [this]{ return !q_.empty(); }); T val = std::move(q_.front()); q_.pop(); return val; }};Vorteile: Einfachheit, in der Standardbibliothek enthalten.
Nachteile: Sperren bei jeder Operation, mögliche Contention und Prioritätsinversion.
2. boost::lockfree::queue — Lock-freie Warteschlange
Die Boost-Bibliothek bietet Lock-freie Datenstrukturen auf Basis von CAS-Operationen. boost::lockfree::queue ist eine sperrfreie Multithread-Warteschlange, die einen festen oder dynamischen Speicherpool verwendet.
#include <boost/lockfree/queue.hpp>
boost::lockfree::queue<int> queue(128); // feste Größe
void producer() { for (int i = 0; i < 1000; ++i) { while (!queue.push(i)) { // wenn die Warteschlange voll ist, warten oder verwerfen } }}
void consumer() { int value; while (queue.pop(value)) { process(value); }}Vorteile: Hohe Leistung bei kleinen Warteschlangengrößen, keine Sperren.
Nachteile: Schwieriges Debugging, begrenzte Größe (bei der festen Version), Notwendigkeit von Memory Reclamation.
3. Intel TBB (Threading Building Blocks) — tbb::concurrent_queue
Intel TBB ist eine industrielle Bibliothek für parallele Programmierung. Ihre tbb::concurrent_queue (und tbb::concurrent_bounded_queue) sind für hohe Last optimiert.
#include <tbb/concurrent_queue.h>
tbb::concurrent_bounded_queue<Task> task_queue;task_queue.set_capacity(1024); // Größe begrenzen
// Produzenttask_queue.push(std::move(task));
// KonsumentTask t;if (task_queue.try_pop(t)) { t.execute();}Vorteile: Hervorragende Skalierbarkeit, Unterstützung von gebundenen/ungebundenen Modi, Integration mit dem TBB Task Scheduler.
Nachteile: Lizenz Apache 2.0 (früher GPL), Abhängigkeit von der gesamten TBB-Bibliothek.
4. libdispatch (Grand Central Dispatch) über C++-Binding
GCD ist ein Warteschlangenverwaltungssystem von Apple, verfügbar auf macOS/iOS. Für C++ gibt es einen Wrapper dispatch/queue. Unter Linux kann libdispatch (Open Source) verwendet werden.
#include <dispatch/dispatch.h>
dispatch_queue_t queue = dispatch_queue_create("com.example.myqueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{ // Aufgabe 1});
dispatch_async(queue, ^{ // Aufgabe 2});
dispatch_release(queue);Vorteile: Effizientes Thread-Management, automatische Skalierung auf die Anzahl der Kerne.
Nachteile: Eingeschränkte
Auch in der Bibliothek
Aufgabenwarteschlangen in TypeScript: Überblick über Bibliotheken und Implementierung
Arbeiten mit XML in Swift: Parsen, Erstellen und Verarbeiten von Daten (iOS/macOS)
Caching in C# (.NET): Redis, MemoryCache und andere Lösungen
Überwachung von C++-Anwendungen: Bibliotheken und Tools zur Metrikenerfassung