【多线程】阻塞队列的C++多线程 实现 BlockingQueue
阻塞队列在存放
和获取
队列中的数据时需要使用多线程,一个线程专门负责向队列中存放
元素,另一个线程专门从队列中获取
元素。也可多开辟跟多的线程进行存取。
规范的方法也正是存放
和获取
队列元素分别在不同的线程中实现。
阻塞队列实现:
当队列为空时,从队列
获取
元素的操作将会被阻塞,直到队列中被放入了元素;当队列满时,有两种方案:
方案1: 往队列里
存放
元素的操作也会被阻塞
,直到有元素被从队列中取出或者删除。
具体方法
:定义一个条件变量std::condition_variable not_full_;
在存放
操作时,判断队列为满时,使用not_full_.wait(lock)
阻塞线程;当进行删除
队列元素的操作后,就使用not_full_.notify_all()
来唤醒not_full_.wait(lock)
的线程。【注意区分: 条件变量
not_empty_
是在获取
数据时判断队列是否为空,为空时,使用not_empty_.wait(lock);
,当有队列有新数据进来才会not_empty_.notify_all();
唤醒not_empty_.wait(lock);
的线程。存放操作
和获取操作
需要使用不同的条件变量进行阻塞等待和唤醒】方案2: 不使用阻塞,而是直接删除队列中最老的元素,删除后就直接往队列添加元素了。【本文示例就是方案2】
以上的操作都是基于不同的线程来说的,线程在对阻塞队列进程操作时会被阻塞。
#pragma once#include <condition_variable>
#include <deque>
#include <mutex>
#include <string>
#include <thread>
#include <list>
#include <vector>template <typename T>
class BlockingQueue {public:BlockingQueue(uint size) : size_(size) {}BlockingQueue() {}/*** @brief 向队列中push_back一个元素* **/void put(const T x) {std::unique_lock<std::mutex> lock(mutex_);if (size_ != 0 && queue_.size() > size_) {queue_.pop_front();}queue_.push_back(std::move(x));not_empty_.notify_all(); //有新数据push进来后就唤醒所有wait的线程}/*** @brief 获取队列中第一个元素(不是最新元素)* 元素一旦获取,就从队列中删除* **/T take() {std::unique_lock<std::mutex> lock(mutex_);while (queue_.empty()) {not_empty_.wait(lock); //如果队列为空,线程就在此阻塞挂起,等待唤醒}const T front = queue_.front();queue_.pop_front();return front;}/*** @brief 取出队列中第一个元素(取出后就从队列中删除),并push_back到一个vector中* **/int take(std::vector<T> *v, size_t count) {std::unique_lock<std::mutex> lock(mutex_);while (queue_.empty()) {not_empty_.wait(lock); //如果队列为空,线程就在此阻塞挂起,等待唤醒}while (!queue_.empty() && count--) {v->push_back(queue_.front());queue_.pop_front();}return v->size();}/*** @brief 根据索引获取队列中对应元素* **/T get(size_t index) {std::unique_lock<std::mutex> lock(mutex_);while (queue_.empty()) {not_empty_.wait(lock);}return queue_.at(index);}size_t size() const {std::unique_lock<std::mutex> lock(mutex_);return queue_.size();}private:mutable std::mutex mutex_;std::condition_variable not_empty_;std::deque<T> queue_;// std::list<T> queue_;//双向链表uint size_ = 0;
};
【多线程】阻塞队列的C++多线程 实现 BlockingQueue相关推荐
- java多线程-阻塞队列BlockingQueue
大纲 BlockingQueue接口 ArrayBlockingQueue 一.BlockingQueue接口 public interface BlockingQueue<E> exte ...
- java 多线程阻塞队列 与 阻塞方法与和非阻塞方法
Queue是什么 队列,是一种数据结构.除了优先级队列和LIFO队列外,队列都是以FIFO(先进先出)的方式对各个元素进行排序的.无论使用哪种排序方式,队列的头都是调用remove()或poll()移 ...
- java多线程阻塞队列_阻塞队列和多线程消费者,如何知道何时停止
我有一个单线程生成器,它创建一些任务对象,然后添加到 ArrayBlockingQueue (具有固定大小) . 我也开始了一个多线程的消费者 . 这是一个固定的线程池( Executors.newF ...
- 阻塞队列的应用 || 多线程的条件判断 一定要用while,而不要用 if
ProdConsTradiDemo.java package thread;import java.util.concurrent.locks.Condition; import java.util. ...
- 一心多用多线程-阻塞队列(5)-CountDownLatch
五.倒数执行机制-CountDownLatch Latch:门闩的意思.根据该类名的意思,我们就可以知道该类在多线中扮演的就是一个倒数门闩的角色,怎么理解呢? 首先呢,我们新建一个CountDownL ...
- 多线程 阻塞队列中的poll与take区别
https://blog.csdn.net/qiuchaoxi/article/details/80359462
- 一心多用多线程-阻塞队列(7)-CyclicBarrier
七.都做好了了就一起执行-CyclicBarrier 在文章(6)中我们谈到一个现象,就是做一道菜有时候是会分出多个工序进行的,当每个工序做好了之后那到菜才能相应的被做出来.文章(6)使用的是Coun ...
- Java多线程学习二十三:什么是阻塞队列
阻塞队列的作用 阻塞队列,也就是 BlockingQueue,它是一个接口,如代码所示: public interface BlockingQueue<E> extends Queue&l ...
- Java并发包--阻塞队列(BlockingQueue)
阻塞队列介绍 在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全"传输"数据的问题.通过这些高效并且线程安全的队列类,为我们快速搭建高质 ...
最新文章
- pytorch中网络loss传播和参数更新理解
- 网红送餐无人车被指用人冒充AI始末:没有人工,就没有智能
- python判断字符串中包含某个字符串_Python中最常用的字符串方法!
- 分割点云数据_3D点云深度学习综述:三维形状分类、目标检测与跟踪、点云分割等...
- python threading lock_python threading之死锁和可重入锁
- IOS开发学习记录第2天之熟悉Xcode常用快捷键
- 公共情报工具automater的基本使用
- 【英语学习】【WOTD】adversary 释义/词源/示例
- java 模板组件_9Tile模板和Tile组件创建复合式网页
- SI4463的数据冲撞解决办法【转】
- Nginx负载均衡配置实例详解(转发学习)留给未来需要的自己
- 视频演示SHAtter越狱iOS 4.1
- ppt画深度学习网络图
- Object.entries()
- tig只看某个作者的提交
- 我用最独特的方式为情人节准备了这些。。。
- 操作系统Topic推荐-AMiner
- 【C#】简繁体转换类
- Java SE 01 概述
- birthday中文是什么_birthday中文怎么读