#pragma once
#include <functional>
#include <memory>
#include <thread>
#include <queue>
#include <condition_variable>
template<typename T>
class CConsumeQueue
{
typedef std::function<void(T)> ConsumeFunction;
public:
//consumeRate: 消耗速率(消息个数/1ms)
CConsumeQueue(int consumeRate, int publishQueueMaxSize = USHRT_MAX);
~CConsumeQueue() { stop(); };
void publish(T data);
void consume(ConsumeFunction consumeFunction);
void stop();
void setConsumeRate(int rate);
int getConsumeRate();
int getPublishQueueLength();
private:
void consumeThreadFunction(ConsumeFunction consumeFunction);
private:
std::thread* m_pThread = nullptr;
//生产者队列
std::queue<T> m_queuePublish;
int m_iConsumeRate;
int m_iPublishQueueMaxSize;
std::condition_variable m_wait;
std::mutex m_mutex;
bool m_isStop = false;
std::chrono::microseconds m_mSleepTime;
};
template<typename T>
int CConsumeQueue<T>::getPublishQueueLength()
{
return m_queuePublish.size();
}
template<typename T>
int CConsumeQueue<T>::getConsumeRate()
{
return m_iConsumeRate;
}
template<typename T>
void CConsumeQueue<T>::setConsumeRate(int rate)
{
if (m_iConsumeRate == rate)
{
return;
}
m_iConsumeRate = rate;
m_mSleepTime = std::chrono::microseconds(1000000 / m_iConsumeRate);
}
template<typename T>
void CConsumeQueue<T>::stop()
{
{
std::unique_lock<std::mutex> locker(m_mutex);
m_isStop = true;
m_wait.notify_all();
}
if (m_pThread)
{
m_pThread->join();
delete m_pThread;
m_pThread = nullptr;
}
}
template<typename T>
void CConsumeQueue<T>::publish(T data)
{
if (m_isStop)
{
return;
}
std::unique_lock<std::mutex> locker(m_mutex);
m_queuePublish.push(data);
if (m_queuePublish.size() > m_iPublishQueueMaxSize)
{
m_queuePublish.pop();
}
m_wait.notify_all();
}
template<typename T>
void CConsumeQueue<T>::consume(ConsumeFunction consumeFunction)
{
m_pThread = new std::thread([=]() {
consumeThreadFunction(consumeFunction);
});
}
template<typename T>
CConsumeQueue<T>::CConsumeQueue(int consumeRate, int publishQueueMaxSize)
{
//m_iConsumeRate = consumeRate;
setConsumeRate(consumeRate);
m_iPublishQueueMaxSize = publishQueueMaxSize;
}
template<typename T>
void CConsumeQueue<T>::consumeThreadFunction(ConsumeFunction consumeFunction)
{
while (!m_isStop)
{
std::unique_lock<std::mutex> locker(m_mutex);
if (m_queuePublish.empty())
{
m_wait.wait(locker);
}
if (m_isStop)
{
return;
}
std::queue<T> consumeQueue;
consumeQueue.swap(m_queuePublish);
locker.unlock();
while (!consumeQueue.empty() && !m_isStop)
{
consumeFunction(consumeQueue.front());
consumeQueue.pop();
std::this_thread::sleep_for(m_mSleepTime);
}
}
}
C++消费者队列简单版
最新推荐文章于 2023-07-22 20:42:04 发布