实用笔记系列5

c++ 同步阻塞队列

SyncQueue.hpp

#pragma once
#include <condition_variable>
#include <iostream>
#include <list>
#include <mutex>

#include "opencv2/opencv.hpp"

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())
        {
            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())
        {
            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
};

extern SyncQueue<cv::Mat> syncQueue;

main.cpp

#include <chrono>
#include <iostream>
#include <thread>
#include "SyncQueue.hpp"

SyncQueue<cv::Mat> syncQueue(5);
void Produce()
{
    for (int i = 0; i < 15; ++i)
    {
        std::this_thread::sleep_for(std::chrono::seconds(1));
		std::string filename = std::to_string(i) + "_" + "dsr.jpg";
		cv::Mat img = cv::imread(filename);
        syncQueue.Put(img);
    }
}

void Consume()
{
    cv::Mat dst;
    for (int i = 0; i < 5; ++i)
    {
        std::this_thread::sleep_for(std::chrono::seconds(1));
        syncQueue.Take(dst);
        std::string filename = std::to_string(i) + "_" + "dst.jpg";
        cv::imwrite(filename, dst);
    }
}

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 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

血_影

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值