C++ 任务队列:实用指南与示例

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:为什么在 C++ 中需要任务队列?



在现代编程中,尤其是在处理多线程应用程序时,经常需要按任务到达的顺序组织执行。任务队列是一种基础模式,它能够有效地在线程之间分配工作、处理 Web 服务器请求、管理后台进程并避免竞态条件。



在 C++ 中,标准库提供了强大的容器 std::queue,非常适合实现任务队列。然而,在实际应用中,不仅需要存储元素,还需要在线程之间安全地传递它们、处理错误并管理任务的生命周期。在本文中,我们将从零开始讲解如何使用现代 C++ 特性(C++11 及更高版本)创建任务队列。



我们将讨论:

  • std::queue 的基本操作
  • 线程安全的任务队列
  • 线程池的实现
  • 优先级队列


1. 使用 std::queue 的基本任务队列



从一个简单的例子开始。std::queue 是一个容器适配器,遵循先进先出(FIFO)原则。它提供了 push()、pop()、front() 和 empty() 方法。



以下是如何组织一个任务队列,其中每个任务都是一个函数(或可调用对象):



#include <iostream>#include <queue>#include <functional>

int main() { // 任务队列,每个任务都是 std::function<void()> std::queue<std::function<void()>> taskQueue;

// 添加任务 taskQueue.push([]() { std::cout << "任务 1 已完成"; }); taskQueue.push([]() { std::cout << "任务 2 已完成"; }); taskQueue.push([]() { std::cout << "任务 3 已完成"; });

// 处理队列 while (!taskQueue.empty()) { auto task = taskQueue.front(); task(); // 执行任务 taskQueue.pop(); // 移除已完成的任务 }

return 0;}


这段代码可以工作,但仅限于单线程模式。如果多个线程同时添加或取出任务,就会产生竞态条件。对于多线程,需要同步机制。



2. 线程安全的任务队列



为了使队列对多线程访问安全,我们使用互斥锁(std::mutex)和条件变量(std::condition_variable)。这是经典的生产者-消费者模式。



线程安全队列的实现:



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

class ThreadSafeQueue {private: std::queue<std::function<void()>> queue_; std::mutex mutex_; std::condition_variable cond_; bool stop_ = false;

public: void push(std::function<void()> task) { std::lock_guard<std::mutex> lock(mutex_); queue_.push(task); cond_.notify_one(); // 通知一个等待的线程 }

std::function<void()> pop() { std::unique_lock<std::mutex> lock(mutex_); cond_.wait(lock, [this]() { return !queue_.empty() || stop_; }); if (stop_ && queue_.empty()) { return nullptr; // 停止信号 } auto task = queue_.front(); queue_.pop(); return task; }

void stop() { std::lock_guard<std::mutex> lock(mutex_); stop_ = true; cond_.notify_all(); // 唤醒所有线程以完成 }};


关键点:

  • std::lock_gu

博客

书籍推荐