c++ 同步阻塞队列
参考:《C++11深入应用》
用同步阻塞队列解决生产者消费者问题。
生产者消费者问题:
有一个生产者在生产产品,这些产品将提供给若干个消费者去消费,为了使生产者和消费者能并发执行,在两者之间设置一个有多个缓冲区的缓冲池,
生产者将它生产的产品放入一个缓冲区中,消费者可以从缓冲区中取走产品进行消费,所有生产者和消费者都是异步方式运行的,但它们必须保持同步,
即不允许消费者到一个空的缓冲区中取产品,也不允许生产者向一个已经装满产品且尚未被取走的缓冲区中投放产品。
//SyncQueue.hpp
#include <list>
#include <mutex>
#include <condition_variable>
#include <iostream> template<typename T>
class SyncQueue
{
private:
bool IsFull() const
{
return m_queue.size() == m_maxSize;
} bool IsEmpty() const
{
return m_queue.empty();
} public:
SyncQueue(int maxSize) : m_maxSize(maxSize)
{
} void Put(const T& x)
{
std::lock_guard<std::mutex> locker(m_mutex); while (IsFull())
{
std::cout << "the blocking queue is full,waiting..." << std::endl;
m_notFull.wait(m_mutex);
}
m_queue.push_back(x);
m_notEmpty.notify_one();
} void Take(T& x)
{
std::lock_guard<std::mutex> locker(m_mutex); while (IsEmpty())
{
std::cout << "the blocking queue is empty,wating..." << std::endl;
m_notEmpty.wait(m_mutex);
} x = m_queue.front();
m_queue.pop_front();
m_notFull.notify_one();
} private:
std::list<T> m_queue; //缓冲区
std::mutex m_mutex; //互斥量和条件变量结合起来使用
std::condition_variable_any m_notEmpty;//不为空的条件变量
std::condition_variable_any m_notFull; //没有满的条件变量
int m_maxSize; //同步队列最大的size
};
测试:
//test.cpp #include "SyncQueue.hpp"
#include <thread>
#include <iostream>
#include <chrono> SyncQueue<int> syncQueue();
void Produce()
{
for (int i = ; i < ; ++i)
{
std::this_thread::sleep_for(std::chrono::seconds());
syncQueue.Put();
std::cout<<"put(888)"<<std::endl;
}
} void Consume()
{
int x = ; for (int i = ; i < ; ++i)
{
std::this_thread::sleep_for(std::chrono::seconds());
syncQueue.Take(x);
std::cout << "take(888)" << std::endl;
}
} int main(void)
{
std::thread producer(Produce);
std::thread consumer1(Consume);
std::thread consumer2(Consume);
std::thread consumer3(Consume);
producer.join();
consumer1.join();
consumer2.join();
consumer3.join(); return ;
}
c++ 同步阻塞队列的更多相关文章
- java的nio之:java的bio流下实现的socket服务器同步阻塞模型和socket的伪异步的socket服务器的通信模型
同步I/O模型的弊端===>每一个线程的创建都会消耗服务端内存,当大量请求进来,会耗尽内存,导致服务宕机 伪异步I/O的弊端分析===>当对Socket的输入流进行读取操作的时候,它会一直 ...
- java高并发系列 - 第25天:掌握JUC中的阻塞队列
这是java高并发系列第25篇文章. 环境:jdk1.8. 本文内容 掌握Queue.BlockingQueue接口中常用的方法 介绍6中阻塞队列,及相关场景示例 重点掌握4种常用的阻塞队列 Queu ...
- 【转载】阻塞队列之三:SynchronousQueue同步队列 阻塞算法的3种实现
一.SynchronousQueue简介 Java 6的并发编程包中的SynchronousQueue是一个没有数据缓冲的BlockingQueue,生产者线程对其的插入操作put必须等待消费者的移除 ...
- 阻塞队列之三:SynchronousQueue同步队列 阻塞算法的3种实现
一.SynchronousQueue简介 Java 6的并发编程包中的SynchronousQueue是一个没有数据缓冲的BlockingQueue,生产者线程对其的插入操作put必须等待消费者的移除 ...
- 并发编程-concurrent指南-阻塞队列-同步队列SynchronousQueue
SynchronousQueue:同步Queue,属于线程安全的BlockingQueue的一种,此队列设计的理念类似于"单工模式",对于每个put/offer操作,必须等待一个t ...
- Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就绪,挂起,运行) ,***协程概念,yield模拟并发(有缺陷),Greenlet模块(手动切换),Gevent(协程并发)
Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就 ...
- 多线程,线程类三种方式,线程调度,线程同步,死锁,线程间的通信,阻塞队列,wait和sleep区别?
重难点梳理 知识点梳理 学习目标 1.能够知道什么是进程什么是线程(进程和线程的概述,多进程和多线程的意义) 2.能够掌握线程常见API的使用 3.能够理解什么是线程安全问题 4.能够知道什么是锁 5 ...
- 死锁,线程协作(同步,阻塞队列,Condition,管道流)
synchronized死锁 package com.thread.demo.deadlock; public class DeadLock { private static Object lock1 ...
- 0038 Java学习笔记-多线程-传统线程间通信、Condition、阻塞队列、《疯狂Java讲义 第三版》进程间通信示例代码存在的一个问题
调用同步锁的wait().notify().notifyAll()进行线程通信 看这个经典的存取款问题,要求两个线程存款,两个线程取款,账户里有余额的时候只能取款,没余额的时候只能存款,存取款金额相同 ...
随机推荐
- Elasticsearch 安装的时候,Unsupported major.minor version 51.0问题的解决
Elasticsearch安装的时候报错 bootstrap/Elasticsearch : Unsupported major.minor version 51.0 网上一般说的方法是,升级或者降级 ...
- java向数据库插入N条数据
为了测试mysql的索引,要向数据库先插入上万条数据,然后再测试.手动插入太麻烦,写了一段代码. 先上代码: package action; import java.sql.Connection; i ...
- TSQL--逻辑查询处理
1. 查询处理可分成逻辑处理和物理处理,逻辑处理上各阶段有特定的顺序,但为优化查询,在保证结果集正确的条件下,物理处理顺序并不按照逻辑处理顺序执行,如果在INNER JOIN时,WHERE语句中的过滤 ...
- Npoi将excel数据导入到sqlserver数据库
/// <summary> /// 将excel导入到datatable /// </summary> /// <param name="filePath&qu ...
- 再编写代码中报错:CS8107 C# 7.0 中不支持功能“xxxxxx”。请使用 7.1 或更高的语言版本。
解决方法:项目右键属性 ---> 生成 ---> 找到最下面的高级按钮,点击高级按钮 ---> 常规 ---> 语言版本 ---> 选择 C#最新次要版本,或者比当前版本 ...
- ubuntu 关闭和开启防火墙
1.关闭ubuntu的防火墙 ufw disable 2开启防火墙 ufw enable 3.卸载了iptables apt-get remove iptables 4.关闭ubuntu中的防火墙的其 ...
- docker安装配置
########################################## #docker安装配置 #环境centos7 #配置docker阿里源 echo '#Docker [docker ...
- kali linux之Audacity
常用音频隐写工具 安装: sudo apt install audacity 初次打开的界面 看波的宽度分辨长短音 比较细的就是短音,代表".",比较粗的就是长音,代表" ...
- Keil软件编程问题归总
Q:KEIL.uVision.RealView.MDK.KEIL C51之间的关系纠葛(比较区别)? A: KEIL是公司的名称,有时候也指KEIL公司的所有软件开发工具,目前2005年Keil由AR ...
- ES6之新增set数据结构
学习set set是ES6中的新增的数据结构,是一种构造函数,类似于数组,但是里面的元素都是唯一的,不重复的. 例如: const set = new Set(); [1,2,3,4,5,2,1,2, ...