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;
}