// file : blockBoundQueue.h
#ifndef YANG_BLOCKBOUNDQUEUE
#define YANG_BLOCKBOUNDQUEUE
#include <mutex>
#include <condition_variable>
#include <queue>
#include <cstdio>
namespace yang{
#define _FULL 4 //
template <typename _Tp>
class BlockBoundQueue
{
public:
BlockBoundQueue(size_t bound = _FULL) :bound_(bound){}
BlockBoundQueue(const BlockBoundQueue&) = delete;
BlockBoundQueue& operator=(const BlockBoundQueue&) = delete;
void push(const _Tp& value)
{
std::unique_lock<std::mutex> lck(mutex_);// 利用RAII技法,将mutex_托管给lck
while (count_ + 1 == bound_)// 用while防止虚假唤醒
{
printf("the queue is full , waiting for the consumer consuming !\n");
notFull_.wait(lck); //等待队列非满条件发生
}
count_++;
queue_.push(value);
notEmpty_.notify_one();//通知队列非空,不能用all,读者自行思考为什么
}
_Tp get()
{
std::unique_lock<std::mutex> lck(mutex_);
while (queue_.empty())
{
printf("the queue is empty , waiting for the producer producing !\n");
notEmpty_.wait(lck);//等待队列为非空
}
_Tp front(queue_.front());
queue_.pop();
count_--;
notFull_.notify_one();//通知队列为非满,请注意不能用all
return front;
}
private:
std::mutex mutex_;
std::condition_variable notEmpty_;
std::condition_variable notFull_;
std::queue<_Tp> queue_;
size_t count_{ 0 };
size_t bound_;
};
}
#endif
//在visual studio 2013上编译运行通过

  

// file : main.cpp
#include <cstdio>
#include <cstdlib>
#include <thread>
#include "BlockBoundQueue.h"
yang::BlockBoundQueue<int> blockboundqueue_;// 全局的缓冲边界队列
const int total = 16; // 商品总数
void consumer(size_t id,size_t n); // 消费者
void producer(size_t id,size_t n); // 生产者
int main()
{
std::thread consumer1(consumer,0, 5);
std::thread consumer2(consumer,1, 5);
std::thread consumer3(consumer,2, 6);
std::thread producer1(producer,0, 8);
std::thread producer2(producer,1, 8);
consumer1.join();
consumer2.join();
consumer3.join();
producer1.join();
producer2.join();
system("pause");
return 0;
}
void consumer(size_t id,size_t n)
{
for (auto i = 0; i < n; ++i)
{
std::this_thread::sleep_for(std::chrono::seconds(2));
int item = blockboundqueue_.get();
printf("the %d^th consumer thread has consumed the %d^th item\n", id,item);
}
} void producer(size_t id,size_t n)
{
for (int i = 0; i < n; ++i)
{
blockboundqueue_.push(i);
printf("the %d^th producer thread has produced the %d^th item\n",id, i);
}
}

【转】https://blog.csdn.net/dhz625/article/details/72026666

用BlockBoundQueue和c++11实现多线程生产者消费者问题的更多相关文章

  1. java+反射+多线程+生产者消费者模式+读取xml(SAX)入数据库mysql-【费元星Q9715234】

    java+反射+多线程+生产者消费者模式+读取xml(SAX)入数据库mysql-[费元星Q9715234] 说明如下,不懂的问题直接我[费元星Q9715234] 1.反射的意义在于不将xml tag ...

  2. Python多线程-生产者消费者模型

    用多线程和队列来实现生产者消费者模型 # -*- coding:utf-8 -*- __author__ = "MuT6 Sch01aR" import threading imp ...

  3. Java实现多线程生产者消费者模式的两种方法

    生产者消费者模式:生产者和消费者在同一时间段内共用同一存储空间,生产者向空间里生产数据,而消费者取走数据.生产者生产一个,消费者消费一个,不断循环. 第一种实现方法,用BlockingQueue阻塞队 ...

  4. 多线程-生产者消费者(synchronized同步)

    正解博客:https://blog.csdn.net/u011863767/article/details/59731447 永远在循环(loop)里调用 wait 和 notify,不是在 If 语 ...

  5. java多线程 生产者消费者模式

    package de.bvb; /** * 生产者消费者模式 * 通过 wait() 和 notify() 通信方法实现 * */ public class Test1 { public static ...

  6. [多线程] 生产者消费者模型的BOOST实现

    说明 如果 使用过程中有BUG 一定要告诉我:在下面留言或者给我邮件(sawpara at 126 dot com) 使用boost::thread库来实现生产者消费者模型中的缓冲区! 仓库内最多可以 ...

  7. Java实现多线程生产者消费者模型及优化方案

    生产者-消费者模型是进程间通信的重要内容之一.其原理十分简单,但自己用语言实现往往会出现很多的问题,下面我们用一系列代码来展现在编码中容易出现的问题以及最优解决方案. /* 单生产者.单消费者生产烤鸭 ...

  8. 操作系统实验 windows编程多线程 生产者消费者问题 画圆画方(内置bug版)

    实验3:随便写的 #include <windows.h> #include <string> #include <stdio.h> #pragma warning ...

  9. java实现多线程生产者消费者模式

    1.概念 生产者消费者模式就是通过一个容器来解决生产者和消费者的强耦合问题.生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消 ...

随机推荐

  1. BeanPostProcessor

    BeanPostProcessor简介 BeanPostProcessor是Spring IOC容器给我们提供的一个扩展接口.接口声明如下: public interface BeanPostProc ...

  2. [HeadFrist-HTMLCSS学习笔记]第五章认识媒体:给网页添加图像

    [HeadFrist-HTMLCSS学习笔记]第五章认识媒体:给网页添加图像 干货 JPEG.PNG.GIF有何不同 JPEG适合连续色调图像,如照片:不支持透明度:不支持动画:有损格式 PNG适合单 ...

  3. 秘制牛肉Gamma阶段项目展示

    秘制牛肉Gamma阶段项目展示 1.团队成员和个人博客 · 左顺:在项目中主要负责后端开发.个人博客 · 袁勤:精通网页项目开发,前端后端都很强,在完成自己后端任务后也会积极帮助其他人的任务.个人博客 ...

  4. 一个sh脚本 同时运行 多个sh脚本

    问题: 原来的启动方式 cd /opt/OpenIMSCore ./pcscf.sh ./icscf.sh ./scscf.sh cd /opt/OpenIMSCore/FHoSS/deploy ./ ...

  5. golang 赋值与声明语法糖使用注意事项

    赋值与声明语法糖 基本用法略, 搜索即可 注意事项 类型推断 := 会自动进行类型推断, 当想要的类型不是自己想要的类型时需要进行类型转换 // i1 默认是 int 类型 i1 := 1 // 当需 ...

  6. jquery如何遍历table,并对table里的某一个单元格进行操作

    1.如何根据每一行的某一列的值进行比较或其他操作,进而修改另一列的值或属性. $("#table_id tbody tr").each(function(){ var a = $( ...

  7. Win10创建mysql8.0桌面快捷方式以及启动mysql.exe闪退问题

    1.先找到mysql的bin目录,将Mysql.exe发送快捷方式到桌面. 2.然后右键选择属性,将目标后面添加上 -uroot -p 我的完整目标如下: E:\mysql-8.0.17-winx64 ...

  8. 详解redis持久化

    我们的Redis必须使用数据持久化吗?如果我们的Redis服务器只作为缓存使用,Redis中存储的所有数据都是从其他地方同步过来的备份,那么就没必要开启数据持久化的选项.Redis提供了将数据定期自动 ...

  9. IScroll中div点击事件触发两次解决办法

    1.网上的同学说的,直接修改源代码,但是这种方法可能会影响到现有的程序. 搜索onBeforeScrollStart方法,将其中的preventDefault禁止掉搜索_end方法,将其中模拟clic ...

  10. Ubuntu Docker搭建GitLab以及常规配置使用

    安装启动实例 1.首先创建一个目录用于存放配置 sudo docker pull docker.io/gitlab/gitlab-ce sudo mkdir -p /root/docker/gitla ...