C++ 任务调度器:完整指南
任务调度器 (Task Scheduler) 是一个强大的工具,可以自动在特定时间点或按指定周期执行代码。在 C++ 中实现这样的调度器需要理解多线程、同步以及时间间隔的处理。在本文中,我们将讲解如何使用标准 C++ 库(C++11 及更高版本)从头创建自己的任务调度器。
调度器的主要组件
任何任务调度器都由几个关键元素组成:
- 任务存储 — 用于存储已调度任务的队列或容器。
- 定时器 — 确定任务何时应执行的机制。
- 线程池 — 用于并行执行任务,而不阻塞主线程。
- 取消机制 — 能够在任务执行前取消任务。
单线程的简单调度器实现
从一个基础示例开始,任务在后台线程中顺序执行:
#include <iostream>#include <thread>#include <chrono>#include <functional>#include <queue>#include <mutex>#include <condition_variable>
class TaskScheduler {public: // 调度一个带延迟的任务 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(); }
// 在单独的线程中启动调度器 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(); // 执行任务 } 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 << "任务 1 在 2 秒后执行"; }, 2000);
scheduler.schedule([]() { std::cout << "任务 2 在 1 秒后执行"; }, 1000);
std::this_thread::sleep_for(std::chrono::seconds(3)); scheduler.stop(); return 0;}带线程池的调度器实现并行执行
对于更复杂的场景,当任务可能需要长时间执行时,最好使用线程池。以下是一个最小线程池的示例:
#include <vector>#include <queue>#include <thread>#include <mutex>#include <condition_variable>#include <f