C++11实现生产者消费者模型

C++11 实现单生产者单消费者模型 #include <queue> #include <chrono> #include <mutex> #include <thread> #include <iostream> #include <condition_variable> int main() { std::queue<int> pr... 阅读详情

C++11实现生产者消费者模型

  • 生产者消费者模型是什么
    简单地举个例子,一个线程(或者进程)在往一个区域(可以使内存或其他地方)写数据,而同时有另外一个线程在取数据,这就存在了一个问题,存储的区域有限,数据存满了写数据的线程怎么办,还有数据空了,取数据的线程怎么处理,这时候就需要该模型来处理了。
  • 原理
    存储的数据的区域可以用一个队列来模拟,然后我们通过C++11提供的条件变量来通知写入线程在数据不满的时候进行写入,在数据满的时候挂起,对读取线程也是同理。
  • 需要C++11前置知识
    此次需要用到std::mutex互斥锁,用来防止写入与读取线程竞争数据区域。搭配使用std::unique_lock,利用RAII来控制锁释放,也是因为条件变量的存在需要该类型。
    当然还需要最重要的一个std::condition_variable,条件变量。介绍一下几个重要的函数。
  • wait()成员函数
void wait( std::unique_lock<std::mutex>& lock );
//Predicate 谓词函数,可以普通函数或者lambda表达式
template< class Predicate >
void wait( std::unique_lock<std::mutex>& lock, Predicate pred );

wait函数会阻塞当前线程直到条件变量被通知,或者被操作系统虚假唤醒(系统Bug),可选地循环知道满足某谓词

  • notify成员函数
void notify_one() noexcept;
若任何线程在 *this 上等待,则调用 notify_one 会解阻塞(唤醒)等待线程之一。

void notify_all() noexcept;
若任何线程在 *this 上等待,则解阻塞(唤醒)全部等待线程。
  • 实现代码
#include <mutex>
#include <condition_variable>
#include <deque>
#include <vector>
#include <iostream>
#include <thread>

std::mutex g_mtxDegue;
std::mutex g_mtxCout;
std::condition_variable g_cv_not_empty;
std::condition_variable g_cv_not_full;
std::deque<int> g_deque;
int g_itemIndex = 0;

const int g_kItemSize = 30;
const int g_kDequeSize = 10;

void produceItem()
{
	std::this_thread::sleep_for(std::chrono::seconds(1));
	std::unique_lock<std::mutex> lock(g_mtxDegue);
	g_cv_not_full.wait(lock, []() { return g_deque.size() < g_kDequeSize; });

	++g_itemIndex;
	g_deque.push_back(g_itemIndex);
	{
		std::lock_guard<std::mutex> lock_guard(g_mtxCout);
		std::cout << "produce item " << g_itemIndex << std::endl;
	}
	lock.unlock();
	g_cv_not_empty.notify_all();
}

void consumeItem()
{
	std::this_thread::sleep_for(std::chrono::seconds(2));
	std::unique_lock<std::mutex> lock(g_mtxDegue);
	g_cv_not_empty.wait(lock, []() { return !g_deque.empty(); });

	int itemIndex = g_deque.front();
	g_deque.pop_front();
	{
		std::lock_guard<std::mutex> lock_guard(g_mtxCout);
		std::cout << "\tconsume item " << itemIndex << std::endl;
	}
	lock.unlock();
	g_cv_not_full.notify_one();
}

void produceTask()
{
	int count = g_kItemSize;
	while (count--)
	{
		produceItem();
	}
}

void consumeTask()
{
	int count = g_kItemSize;
	while (count--)
	{
		consumeItem();
	}
}

//单生产者单消费者模型
void consumeProduceTest()
{
	std::vector<std::thread> threads;
	threads.push_back(std::thread(produceTask));
	threads.push_back(std::thread(consumeTask));
	for (int i = 0; i < 2; i++)
		threads.at(i).join();
}

这里只是简单地给出了单个生产者和单个消费者的示例,对于单对多、多对单和多对多,需要考虑的是生产者间或者消费者之间对数据数量这个值的互斥。

c++11实现生产者消费者模型 1.生产者与消费者模型 一个场所,两种角色,三种关系。(场所:线程安全的队列) 2.优点 解耦、支持忙闲不均、支持并发 3.实现 用到互斥锁,条件变量 #include <thread> #include <mutex> #include <deque> #include <vector> #include &lt... 阅读详情

相关推荐

C++11生产者消费者模型:从互斥锁到条件变量的完整实现指南

生产者消费者模型是并发编程中的核心范式,用于解耦数据生产与消费过程,提升系统吞吐量。其原理基于共享缓冲区与线程同步机制,通过互斥锁保证数据访问的原子性,利用条件变量实现线程间的高效等待与通知。在C++11标准中,std::thread、std::mutex和std::condition_variable等组件为这一模型提供了标准化实现基础,显著提升了代码的可移植性与安全性。该模型的技术价值在于平衡生产与消费速度差异,避免忙等待造成的CPU资源浪费,广泛应用于网络服务器请求队列、GUI消息泵及数据处理流水线等

weixin_29973493的博客 266

C++11生产者消费者模型

在这个例子中,我们定义了一个大小为5的缓冲区,并实现了一个简单的生产者消费者模型。消费者线程不断地从缓冲区取出物品消费,如果缓冲区为空则等待生产者生产。在线程之间的等待和唤醒过程中,我们使用了互斥锁和条件变量来保证线程安全。std::condition_variable:条件变量,用于线程之间的通信,等待和唤醒线程。std::unique_lock:std::mutex的RAII封装,可以自动释放锁。std::mutex:互斥锁,用于保护共享资源,防止多个线程同时修改同一个资源。

QtCompany的博客 327

UNIX(多线程):20---生产者消费者实例

本文将综合运用 C++11 中的新的基础设施(主要是多线程、锁、条件变量)来阐述一个经典问题——生产者消费者模型,并给出完整的解决方案。生产者消费者问题是多线程并发中一个非常经典的问题,...

yolo模型训练找我,AI游戏合作找我 574

C++语法|C++11标准实现生产者消费者模型

在多线程编程中,生产者-消费者问题是一个经典的同步问题,它涉及到两种类型的线程:生产者和消费者。生产者负责生成数据放入缓冲区,而消费者则从缓冲区中取出数据。本文将详细介绍如何使用 C++11 的新特性来实现这一模型。首先,定义了一个名为Queue的类,它是生产者和消费者共享的队列。该队列内部使用std::queue来存储数据,并配有std::mutex和std::condition_variable来实现线程同步。put方法:当生产者生成一个新的物品时,首先会获取互斥锁。

糖炒栗子 1446

Qt C++11 生产者消费者模式类

使用Qt 和 C++11 的std::mutex 和 std::condition_variable 实现一个演示生产者消费者模式的Qt工程。

生产者 消费者 模式 c++

生产者 消费者 模式 c++ 算是老外写的一个使用demo 可以参考一下

【C++】【设计模式之】生产者-消费者模型(理论讲解及实现)

一、什么是生产者-消费者模型 1、简单理解生产者-消费者模型 假设有两个进程(或线程)A、B和一个固定大小的缓冲区,A进程生产数据放入缓冲区,B进程从缓冲区中取出数据进行计算,这就是一个简单的生产者-消费者模型。这里的A进程相当于生产者,B进程相当于消费者。 2、为什么要使用生产者-消费者模型 在多线程开发中,如果生产者生产数据的速度很快,而消费者消费数据的速度很慢,那么生产者就必须等待消费者消费完数据才能够继续生产数据,因为生产过多的数据可能会导致存储不足;同理如果消费者的速度大于生产者那么消费者就会经常

格物致知 1万+

【凌智视觉模块】rv1106 部署 pp-humseg 模型

人像分割技术实现摘要 人像分割是利用计算机视觉技术将图像/视频中的人物与背景分离的像素级处理技术。凌智视觉模块基于RV1106芯片开发,支持高效视觉模型部署。当前主流方法包括PP-HumanSeg、BiSeNet等深度学习模型,其中PP-HumanSegV2以96.63% mIoU精度和63FPS手机端速度成为SOTA方案。 实现流程包含: 初始化RKNN模型后端 图像预处理(尺寸调整、颜色空间转换) 执行模型推理 后处理(概率解码、动态阈值分割、形态学优化) 代码实现要点: 使用RKNPU2Backend

m0_50786932的博客 986

C++11 线程库实现生产者-消费者模型

C++11 线程库实现生产者-消费者模型

qq_45981338的博客 1010

OpenClaw智能体应用第一集--飞书多智能体配置

本文介绍了智能体(Agent)的核心概念与配置实践。Agent作为独立作用域的"大脑",包含模型(认知引擎)、记忆系统(短期/长期记忆)、人设(角色定义)、工具(外部能力调用)、规划执行(任务拆解)、运行环境等核心要素。每个Agent拥有唯一agentId标识,通过accountId区分渠道账号,Binding机制实现消息路由。实践部分展示了通过命令行配置多个智能体(如writer)的过程,包括插件注册和工具加载。系统支持多Agent架构,可根据不同场景需求灵活配置专属智能体。

weixin_44626085的博客 1747

SAP FI 提示没有为会计年度0 定义版本2025 GP626

SAP 错误 GP626 是一个常见的系统消息,通常表示某个会计年度的版本(如版本 0)未被定义或未激活。:在执行某些事务(如创建采购订单、过账凭证或维护成本中心)时,系统会检查相关版本是否已定义。的“Settings for Each Fiscal Year”界面中,选择一个已激活的会计年度。的“Settings for Each Fiscal Year”界面中,找到未激活的会计年度。:在控制范围(Controlling Area)中,未为指定的会计年度定义版本 0。如果没有,添加或复制现有年度的设置。

GAVIN 2491

再谈多线程模型之生产者消费者(单一生产者和多消费者 )(c++11实现)

再谈多线程模型之生产者消费者(单一生产者和多消费者 )(c++11实现)

whl0071的专栏 973

Twin Builder CFD 示例:构建、验证和评估静态 ROM

通过我们构建、验证和评估静态 ROM 的综合指南,释放 Twin Builder CFD 的潜力。

jkh920184196的博客 1103

【多线程同步】C++11实现生产者-消费者模型

本文实现了一个线程安全的阻塞队列BlockingQueue,支持多生产者-多消费者模型。队列使用互斥锁和条件变量实现同步,当队列满时生产者等待,空时消费者等待。主程序创建了2个生产者和2个消费者线程,生产者生成100个数据项后结束,消费者收到特殊值(-1)作为终止信号。通过线程安全打印和条件变量通知机制,实现了线程间的安全通信与协调,最终所有线程都能正确完成工作。该设计展示了C++多线程编程中互斥锁、条件变量等同步原语的使用方法。

2502_94470881的博客 445

告别代码恐惧!用KRobot图形化编程,10分钟搞定Arduino巡线小车(附完整接线图)

本文介绍如何使用KRobot图形化编程工具快速搭建Arduino巡线小车,无需编写代码。从硬件准备到逻辑构建,详细讲解传感器数据处理、电机控制优化及高级功能扩展,帮助教育工作者和创客爱好者10分钟内完成项目。

weixin_30632089的博客 395

python爬取巨潮资讯网所有股票年报数据

爬虫获取巨潮资讯网数据

qq_42752524的博客 6117

C++11生产者消费者模型实现

前面八章介绍了 C++11 并发编程的基础(抱歉哈,第五章-第八章还在草稿中),本文将综合运用 C++11 中的新的基础设施(主要是多线程、锁、条件变量)来阐述一个经典问题——生产者消费者模型,并给出完整的解决方案。 生产者消费者问题是多线程并发中一个非常经典的问题,相信学过操作系统课程的同学都清楚这个问题的根源。本文将就四种情况分析并介绍生产者和消费者 问题,它们分别是:单生产者-单消费者...

weixin_30687811的博客 139

ABAP 7.40 FOR 表达式与 REDUCE 构造运算符深度解析:从语法新特性到真实项目实践

ABAP 7.40引入了FOR和REDUCE表达式语法,使代码更简洁和函数式。FOR支持内表迭代和条件迭代,可配合VALUE构造新内表,替代传统LOOP。REDUCE用于归约运算,将多值折叠为单一结果,如求和、拼接等。这些新特性让ABAP更现代化,与SAP新架构协同更好,提升了开发效率和代码可读性。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 319

再谈多线程模型之生产者消费者(多生产者和单一消费者 )(c++11实现)

0.关于 为缩短篇幅,本系列记录如下:再谈多线程模型之生产者消费者(基础概念)(c++11实现)再谈多线程模型之生产者消费者(单一生产者和单一消费者)(c++11实现)再谈多线程模型之生产者消费者(单一生产者和多消费者)(c++11实现)再谈多线程模型之生产者消费者(多生产者和单一消费者 )(c++11实现)【本文】再谈多线程模型之生产者消费者(多生产者和多消费者 )(c++11实现)再谈多线程...

知其所以然 90

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

再谈多线程模型之生产者消费者(单一生产者和多消费者 )(c++11实现)

0.关于 为缩短篇幅,本系列记录如下:再谈多线程模型之生产者消费者(基础概念)(c++11实现)再谈多线程模型之生产者消费者(单一生产者和单一消费者)(c++11实现)再谈多线程模型之生产者消费者(单一生产者和多消费者)(c++11实现)【本文】再谈多线程模型之生产者消费者(多生产者和单一消费者 )(c++11实现)再谈多线程模型之生产者消费者(多生产者和多消费者 )(c++11实现)再谈多线程...

知其所以然 80

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

再谈多线程模型之生产者消费者(单一生产者和单一消费者)(c++11实现)

0.关于 为缩短篇幅,本系列记录如下:再谈多线程模型之生产者消费者(基础概念)(c++11实现)再谈多线程模型之生产者消费者(单一生产者和单一消费者)(c++11实现)【本文】再谈多线程模型之生产者消费者(单一生产者和多消费者)(c++11实现)再谈多线程模型之生产者消费者(多生产者和单一消费者 )(c++11实现)再谈多线程模型之生产者消费者(多生产者和多消费者 )(c++11实现)再谈多线程...

知其所以然 80

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

再谈多线程模型之生产者消费者(多生产者和多消费者 )(c++11实现)

0.关于 为缩短篇幅,本系列记录如下:再谈多线程模型之生产者消费者(基础概念)(c++11实现)再谈多线程模型之生产者消费者(单一生产者和单一消费者)(c++11实现)再谈多线程模型之生产者消费者(单一生产者和多消费者)(c++11实现)再谈多线程模型之生产者消费者(多生产者和单一消费者 )(c++11实现)再谈多线程模型之生产者消费者(多生产者和多消费者 )(c++11实现)【本文】再谈多线程...

知其所以然 111

C++学习(11) ——C++11线程库(生产者消费者模型实现)

只需要在打印日志的时候加一个专门的锁就好了,但是在这我想尝试一下另一种方法,就是在之前我在写stm32的项目时的启发,我们可以创建一个队列,将待打印的数据放入队列当中,输出任务就只需要从队列里边取数据输出就可以了,这样既可以解决打印错乱的问题,也可以正确的反应,各个线程真实的执行顺序。对于早期的C++语言而言,如果想使用线程,我们需要根据不同的平台使用不用的接口,比如:在Linux平台上,我们需要借助POSIX标准的线程库,在windows上需要借助windows线程库,因为C++自己没有独立的线程库。

weixin_46640900的博客 189

C++11生产者消费者模型:用互斥锁与条件变量实现线程安全队列

在并发编程中,线程同步是确保多线程程序正确性的核心技术。其核心原理是通过互斥机制保护共享资源,结合条件变量实现线程间的协调通信。这项技术的价值在于解决数据竞争和竞态条件问题,保障数据一致性,广泛应用于任务队列、消息传递、数据缓冲等场景。本文以C++11标准库的std::mutex和std::condition_variable为基础,深入解析如何构建一个健壮的线程安全队列,并探讨了优雅关闭、虚假唤醒处理等工程实践要点,为高并发系统开发提供可靠解决方案。

weixin_30768881的博客 294
下一篇: C++设计模式之模板工厂模式
小乖zypher
博客等级 码龄9年 4粉丝 5原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值