C++ Aufgabenplaner: Erstellung und Verwaltung von Aufgaben

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

C++ Aufgabenplaner: Vollständige Anleitung



Ein Aufgabenplaner (Task Scheduler) ist ein leistungsstarkes Werkzeug, mit dem Sie die Ausführung von Code zu bestimmten Zeitpunkten oder in festgelegten Intervallen automatisieren können. In C++ erfordert die Implementierung eines solchen Planers ein Verständnis von Multithreading, Synchronisation und der Arbeit mit Zeitintervallen. In diesem Artikel werden wir erläutern, wie Sie mit der Standard-C++-Bibliothek (C++11 und neuer) einen eigenen Aufgabenplaner von Grund auf erstellen.



Grundlegende Komponenten des Aufgabenplaners

Jeder Aufgabenplaner besteht aus mehreren Schlüsselelementen:

  • Aufgabenspeicher — eine Warteschlange oder ein Container zum Speichern geplanter Aufgaben.
  • Timer — ein Mechanismus, der bestimmt, wann eine Aufgabe ausgeführt werden soll.
  • Thread-Pool — für die parallele Ausführung von Aufgaben ohne Blockierung des Hauptthreads.
  • Abbruchmechanismus — die Möglichkeit, eine Aufgabe vor ihrer Ausführung abzubrechen.


Einfache Implementierung eines Aufgabenplaners mit einem Thread

Beginnen wir mit einem grundlegenden Beispiel, bei dem Aufgaben nacheinander in einem Hintergrundthread ausgeführt werden:



#include <iostream>#include <thread>#include <chrono>#include <functional>#include <queue>#include <mutex>#include <condition_variable>

class TaskScheduler {public: // Plant eine Aufgabe mit einer Verzögerung void schedule(std::function<void()> task, int delay_ms) { std::lock_guard<std::mutex> lock(mutex_); tasks_.push({std::chrono::steady_clock::now() + std::chrono::milliseconds(delay_ms), task}); cv_.notify_one(); }

// Startet den Planer in einem separaten Thread void start() { worker_ = std::thread([this]() { while (!stop_) { std::unique_lock<std::mutex> lock(mutex_); if (tasks_.empty()) { cv_.wait(lock, [this]() { return !tasks_.empty() || stop_; }); } if (stop_) break;

auto now = std::chrono::steady_clock::now(); auto& top = tasks_.top(); if (top.time <= now) { auto task = top.task; tasks_.pop(); lock.unlock(); task(); // Führt die Aufgabe aus } else { cv_.wait_until(lock, top.time); } } }); }

void stop() { stop_ = true; cv_.notify_all(); if (worker_.joinable()) worker_.join(); }

private: struct Task { std::chrono::steady_clock::time_point time; std::function<void()> task; bool operator>(const Task& other) const { return time > other.time; } };

std::priority_queue<Task, std::vector<Task>, std::greater<Task>> tasks_; std::mutex mutex_; std::condition_variable cv_; std::thread worker_; bool stop_ = false;};

int main() { TaskScheduler scheduler; scheduler.start();

scheduler.schedule([]() { std::cout << "Aufgabe 1 nach 2 Sekunden ausgeführt"; }, 2000);

scheduler.schedule([]() { std::cout << "Aufgabe 2 nach 1 Sekunde ausgeführt"; }, 1000);

std::this_thread::sleep_for(std::chrono::seconds(3)); scheduler.stop(); return 0;}


Planer mit Thread-Pool für parallele Ausführung

Für komplexere Szenarien, in denen Aufgaben lange ausgeführt werden können, ist es besser, einen Thread-Pool zu verwenden. Hier ist ein Beispiel mit einem minimalen Pool:



#include <vector>#include <queue>#include <thread>#include <mutex>#include <condition_variable>#include <f                    

Empfehlungen