【多线程】阻塞队列的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的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Linux】31. ffmpeg常用命
- 下一篇: 【数据结构与算法】5. C++中 lis