C++实现生产者与消费者模式方式

 更新时间:2025年12月28日 09:24:44   作者:star-keke  
多线程工作池示例:创建固定数量的工作线程,通过条件变量竞争任务队列,确保任务均匀分发,任务队列读写操作由互斥锁保护,避免竞争,使用`notify_one()`唤醒空闲线程,`notify_all()`停止时唤醒所有线程退出,适用于CPU/IO密集型任务

多线程工作池

  • 创建workerCount个工作线程(示例中为 3 个),每个线程执行相同的workerLoop逻辑。
  • 线程通过condition_variable竞争任务队列中的任务,确保任务被均匀分发。

线程安全保障

  • 任务队列的读写仍通过std::mutex保护,避免多线程竞争导致的数据错乱。
  • cv.notify_one()每次唤醒一个线程处理任务,cv.notify_all()在停止时唤醒所有线程退出。

任务分发逻辑

  • 生产者(主线程)提交任务时,通过notify_one()唤醒空闲线程,避免线程忙等。
  • 多个工作线程同时消费任务,提升任务处理效率(尤其适合 CPU/IO 密集型任务)。
#include <iostream>
#include <mutex>
#include <condition_variable>
#include <queue>
#include <functional>
#include <chrono>
#include <thread>
#include <vector>

// 任务队列类型
using Task = std::function<void()>;

int main() {
    std::mutex mtx;
    std::condition_variable cv;
    std::queue<Task> taskQueue;
    bool stop = false; // 退出标志
    const size_t workerCount = 3; // 工作线程数量
    std::vector<std::thread> workers; // 工作线程列表

    // ========== 工作线程循环:多线程消费任务 ==========
    auto workerLoop = [&](int workerId) {
        while (true) {
            Task task;

            // 加锁,获取任务或检测退出信号
            {
                std::unique_lock<std::mutex> lock(mtx);
                
                // 等待条件:有任务 或 需要停止
                cv.wait(lock, [&]() {
                    return !taskQueue.empty() || stop;
                });

                // 若停止且任务队列为空,退出循环
                if (stop && taskQueue.empty()) {
                    std::cout << "[线程" << workerId << "] 退出工作循环..." << std::endl;
                    break;
                }

                // 取出队列头部任务(多线程竞争,确保线程安全)
                task = std::move(taskQueue.front());
                taskQueue.pop();
                std::cout << "[线程" << workerId << "] 取出任务,准备执行..." << std::endl;
            } // 解锁,避免执行任务时持有锁

            // 执行任务
            if (task) {
                task();
            }
        }
    };

    // ========== 创建多个工作线程 ==========
    for (int i = 0; i < workerCount; ++i) {
        workers.emplace_back(workerLoop, i);
    }

    // ========== 模拟提交任务(生产者逻辑) ==========
    auto submitTask = [&](Task task) {
        std::lock_guard<std::mutex> lock(mtx);
        taskQueue.push(std::move(task));
        std::cout << "提交任务,当前队列大小:" << taskQueue.size() << std::endl;
        cv.notify_one(); // 唤醒一个等待的工作线程
    };

    // 批量提交10个任务
    for (int i = 0; i < 10; ++i) {
        submitTask([i]() {
            std::cout << "执行任务" << i << ":线程ID=" << std::this_thread::get_id() << std::endl;
            std::this_thread::sleep_for(std::chrono::milliseconds(200)); // 模拟任务耗时
        });
    }

    // 等待所有任务执行(可选,也可通过队列状态判断)
    std::this_thread::sleep_for(std::chrono::seconds(3));

    // ========== 停止所有工作线程 ==========
    {
        std::lock_guard<std::mutex> lock(mtx);
        stop = true;
        cv.notify_all(); // 唤醒所有等待的线程,确保全部退出
        std::cout << "\n通知所有线程停止..." << std::endl;
    }

    // 等待所有工作线程结束
    for (auto& worker : workers) {
        if (worker.joinable()) {
            worker.join();
        }
    }

    std::cout << "程序结束" << std::endl;
    return 0;
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • C++新特性详细分析基于范围的for循环

    C++新特性详细分析基于范围的for循环

    C++11这次的更新带来了令很多C++程序员期待已久的for range循环,每次看到javascript, lua里的for range,心想要是C++能有多好,心里别提多酸了。这次C++11不负众望,再也不用羡慕别家人的for range了。下面看下C++11的for循环的新用法
    2022-04-04
  • C++详细讲解内存管理工具primitives

    C++详细讲解内存管理工具primitives

    文章向大家介绍C++内存管理primitives,主要包括primitives使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下
    2022-06-06
  • 详解c++实现信号槽

    详解c++实现信号槽

    这篇文章主要为大家介绍了c++实现信号槽,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2021-12-12
  • C语言中交换int型变量的值及转换为字符数组的方法

    C语言中交换int型变量的值及转换为字符数组的方法

    这篇文章主要介绍了C语言中交换int型变量的值及转换为字符数组的方法,讲解了以不同进制将整型数字转换成字符数组,需要的朋友可以参考下
    2016-04-04
  • 带你了解C++初阶之引用

    带你了解C++初阶之引用

    这篇文章主要为大家介绍了C++初阶之引用,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-01-01
  • dev-c++创建lib(静态链接库)文件的实现步骤

    dev-c++创建lib(静态链接库)文件的实现步骤

    本文主要介绍了dev-c++创建lib(静态链接库)文件的实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • C++版图书管理系统

    C++版图书管理系统

    这篇文章主要为大家详细介绍了C++版图书管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • 海量数据处理系列之:用C++实现Bitmap算法

    海量数据处理系列之:用C++实现Bitmap算法

    本篇文章是对用C++实现Bitmap算法进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • C++多态定义及实现深度剖析

    C++多态定义及实现深度剖析

    多态也是面向对象程序设计的重要特性,它都是配合继承来使用,多态可以增加程序设计的灵活性,这篇文章主要介绍了C++多态定义及实现的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2025-09-09
  • C语言单链表遍历与求和示例解读

    C语言单链表遍历与求和示例解读

    我们在学习编程的过程中,虽然有些语法很简单,但是我们还是要做多题。不做题是发现不了问题的,发现问题我们就可以“对症下药”,进行查漏补缺了。刷题可以先从简单题开始刷,熟练之后再做一些可以提升自己能力的题
    2022-07-07

最新评论