前节写的Repository类只能存储一种类型,这一节考虑写成模版类,同时修改TakeData()接口,可以设置超时时间。
具体代码如下:
- #ifndef REPOSITORY_H
#define REPOSITORY_H
#include <mutex>
#include <condition_variable>
#include <atomic>
#include <QQueue>
#include <QDebug>
template<typename T>
class Repository
{
public:
Repository()
{
m_queue_max_length = 100;
m_bStop = false;
}
void AddData(const T &data)
{
std::unique_lock<std::mutex> lock(m_queue_mutex);
while (m_queue.size() > m_queue_max_length)
{
//qDebug() << "Queue is full";
m_queue_not_full.wait(lock);
}
m_queue.enqueue(data);
//qDebug() << QString("Queue add data [%1]").arg(data);
m_queue_not_empty.notify_all();
lock.unlock();
}
bool TakeData(T& out, int timeout=0)
{
std::unique_lock<std::mutex> lock(m_queue_mutex);
while (m_queue.size() <= 0)
{
if (timeout <= 0)
m_queue_not_empty.wait(lock);
else
{
if (m_queue_not_empty.wait_for(lock, std::chrono::milliseconds(timeout)) == std::cv_status::timeout)
return false;
}
}
out = m_queue.dequeue();
m_queue_not_full.notify_all();
lock.unlock();
//std::cout << "queue get data:" << data << " id=" << std::this_thread::get_id() << std::endl;
return true;
}
void Stop(){m_bStop = true;}
bool IsStop(){return m_bStop;}
int Count(){return m_queue.size();}
void SetQueueMaxSize(int nMax){m_queue_max_length = nMax;}
private:
Repository(const Repository<T>&);
Repository<T>& operator=(const Repository<T>& );
private:
QQueue<T> m_queue;
std::condition_variable m_queue_not_empty;
std::condition_variable m_queue_not_full;
std::mutex m_queue_mutex;
int m_queue_max_length;
std::atomic<bool> m_bStop;
};
#endif // REPOSITORY_H