新闻中心

c++ 怎么实现一个阻塞队列_c++多线程通信与阻塞队列实现方法

2025-11-18
浏览次数:
返回列表
阻塞队列通过互斥锁和条件变量实现线程安全的生产者-消费者模型,支持固定容量下的阻塞插入与提取,适用于任务调度与线程间通信。

c++ 怎么实现一个阻塞队列_c++多线程通信与阻塞队列实现方法

在C++多线程编程中,阻塞队列是线程间通信的常用工具。它允许一个或多个生产者线程向队列添加数据,同时一个或多个消费者线程从队列获取数据。当队列为空时,消费者线程会被阻塞,直到有新数据进入;当队列满时(如果是有界队列),生产者线程也会被阻塞,直到有空间可用。

使用标准库实现阻塞队列

借助 std::queuestd::mutexstd::condition_variablestd::unique_lock,可以轻松实现一个线程安全的阻塞队列。

示例代码:

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

template<typename T>
class BlockingQueue {
private:
    std::queue<T> data_queue;
    mutable std::mutex mtx;
    std::condition_variable not_empty;
    std::condition_variable not_full;
    size_t max_size;

public:
    explicit BlockingQueue(size_t max_sz = 1000) : max_size(max_sz) {}

    void push(const T& item) {
        std::unique_lock<std::mutex> lock(mtx);
        not_full.wait(lock, [this] { return data_queue.size() < max_size; });
        data_queue.push(item);
        not_empty.notify_one();
    }

    void pop(T& item) {
        std::unique_lock<std::mutex> lock(mtx);
        not_empty.wait(lock, [this] { return !data_queue.empty(); });
        item = data_queue.front();
        data_queue.pop();
        not_full.notify_one();
    }

    bool try_pop(T& item) {
        std::unique_lock<std::mutex> lock(mtx);
        if (data_queue.empty()) {
            return false;
        }
        item = data_queue.front();
        data_queue.pop();
        not_full.notify_one();
        return true;
    }

    bool empty() const {
        std::lock_guard<std::mutex> lock(mtx);
        return data_queue.empty();
    }

    size_t size() const {
        std::lock_guard<std::mutex> lock(mtx);
        return data_queue.size();
    }
};

多线程通信场景中的使用方式

阻塞队列常用于生产者-消费者模型。以下是一个简单示例,展示两个线程如何通过阻塞队列通信。

int main() {
    BlockingQueue<int> queue(5);  // 最多容纳5个元素

    std::thread producer([&]() {
        for (int i = 0; i < 10; ++i) {
            queue.push(i);
            std::cout << "生产: " << i << "\n";
        }
    });

    std::thread consumer([&]() {
        for (int i = 0; i < 10; ++i) {
            int value;
            queue.pop(value);
            std::cout << "消费: " << value << "\n";
        }
    });

    producer.join();
    consumer.join();

    return 0;
}

关键点说明与建议

实现阻塞队列时需要注意几个核心机制:

Whimsical Whimsical

Whimsical推出的AI思维导图工具

Whimsical 182 查看详情 Whimsical
  • 条件变量等待必须用循环或 wait 的谓词形式:防止虚假唤醒导致问题。
  • 每次修改队列前必须加锁:保证对 queue 的操作是原子的。
  • 通知机制要正确触发:push 后 notify not_empty,pop 后 notify not_full。
  • 可选支持 try_pop 或超时 pop:提高灵活性,避免无限等待。

如果需要无界队列,可以去掉 max_size 限制和 not_full 条件变量,只保留 not_empty 即可。

应用场景与扩展思路

阻塞队列广泛应用于任务调度、日志系统、消息中间件等场景。

  • 可用于线程池中任务队列的实现。
  • 结合 shared_ptr 支持对象传递,避免拷贝开销。
  • 增加 shutdown 标志位,支持优雅关闭队列,唤醒所有等待线程。

基本上就这些。只要理解了互斥锁和条件变量的协作机制,阻塞队列的实现并不复杂,但非常实用。

以上就是c++++ 怎么实现一个阻塞队列_c++多线程通信与阻塞队列实现方法的详细内容,更多请关注其它相关文章!


# c++  # 尼克  # 如何做全网营销推广平台  # 2017seo每天工作  # 河北区网络营销推广服务  # 谷歌seo优化实操  # 招远网站推广方式  # 商务楼推广营销活动方案  # 未备案影响seo吗  # 铜梁网站建设团队介绍  # seo如何好  # 上海推广网站搭建哪家好  # 内存管理  # 是一个  # 如何用  # 更快  # 多个  # 互斥  # 进阶  # 如何实现  # 多线程  # red  # 标准库  # stream  # ios  # ai  # 工具  # 阻塞队列 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: 1688商家版怎样分析买家画像精准供货_1688商家版分析买家画像精准供货【供货策略】  Go语言中的*string:深入理解字符串指针  Yandex浏览器官方网页版入口 Yandex浏览器最新版官网  Golang如何实现Web文件静态资源服务器_Golang静态资源服务器开发与实践  Lar*el Excel导入时生成自定义递增ID的策略与实践  AI抖音网页版免费视频入口 AI抖音网页端最新视频实时观看  PHP高效扁平化嵌套数组:使用array_merge与数组解包操作符  如何创建没有密码的Windows本地账户_跳过微软账户登录的技巧【教程】  顺丰国际快递查询 国际件官方查询入口  响应式容器内容自动缩放与宽高比维持教程  抖音商城签到领现金是真的吗_抖音商城签到奖励与提现说明  qq游戏大厅官方下载_qq游戏免费下载安装入口  c++ 命名空间怎么用 c++ namespace使用指南  ArrayList与LinkedList操作复杂度详解:遍历与修改  C++的std::mdspan是什么_C++23中用于操作多维数组的非拥有视图  Kafka Streams中基于消息头条件过滤消息的实现指南  LINUX的perf命令入门_LINUX官方性能分析工具的使用与解读  Composer的 "licenses" 命令如何帮助你遵守开源协议_检查项目依赖的许可证合规性  理解Python模块与全局变量的作用域管理  限制HTML日期输入框的日期选择范围  Win11怎么设置鼠标指针速度_Win11提高鼠标指针精确度选项  Animex动漫社网入口地址 Animex动漫社网正版在线入口  J*a里如何使用forEach遍历Map_Map遍历方法说明  Django模型中自动计算可用余额的实现方法  优化LangChain文档加载与ChromaDB集成:解决多文档处理与分块问题  批改网学生版PC登录 批改网官网登录系统入口  age动漫网站入口 age动漫官网直接访问入口  AWS EC2实例间SQL Server连接超时:安全组配置与故障排除指南  Golang如何实现容器化日志收集与分析_Golang容器日志收集分析方法  J*aScript实现单选按钮与关联输入框的联动禁用教程  晋江读书网页版在线登录 晋江读书电脑版官网  4399网页游戏电脑版全新入口 4399电脑端在线玩指南  生成rdflib自定义SPARQL函数:参数匹配与实践指南  三星ZFold5多任务卡顿_Samsung ZFold5流畅度提升  优化MinIO list_objects_v2 操作的性能瓶颈与最佳实践  12306选座系统怎么选连座_12306选座多人连坐操作方法  优化Log4j2控制台输出性能:解决异步日志瓶颈  Discord Slash 命令响应超时问题的异步解决方案  如何使用spryker/configurable-bundles-products-resource-relationship模块解决复杂产品捆绑关系难题  漫蛙manwa官网登录界面_漫蛙漫画网页版主站入口  PDO预处理语句中冒号的正确处理:区分SQL函数格式与命名占位符  Mac怎么查看崩溃日志_Mac控制台错误报告分析  微信客户端如何收红包_微信客户端接收红包使用教程  蛙漫漫画免费阅读入口_蛙漫官方正版无广告纯净版  在Qt QML中通过Python字典动态更新TextEdit内容的教程  邮政快递包裹最新位置 邮政快递实时追踪入口  谷歌邮箱注册显示错误Gmail服务器异常与延迟处理  在J*a中如何在J*a中使用异常机制记录错误日志_异常日志实践经验  海量存储:机器视觉智能化的核心基石  4399免费游戏网址入口 4399小游戏免费入口点开即玩 

搜索