最近做公司项目遇到一个问题,加载20万的日志文件,解析后写入数据库中。做完后发现读文件、解析、写入数据依次搞下来,速度实在是太慢。
所以学习用多线程的来完成这个工作,考虑用生产者消费者模式来完成。
单生产者单消费者模式
头文件
class Repository
{
public:
Repository();
/*!
* brief 存入数据
* param str
*/
void AddData(QString str);
/*!
* brief 取数据
* return
*/
QString GetData();
private:
std::condition_variable m_Queue_Not_Empty; //队列不满信号
std::condition_variable m_Queue_Not_Full; //队列不空信号
std::mutex m_Queue_Mutex; //队列锁
int m_nQueue_Max_Size; //队列最大长度
QQueue<QString> m_queue; //队列,也可以用其他容器、或者数组
};
cpp文件
#include "produce.h"
Repository::Repository()
{
m_nQueue_Max_Size = 10; //默认最大长度为10,可根据需求修改
}
void Repository::AddData(QString str)
{
std::unique_lock<std::mutex> lock(m_Queue_Mutex);
//判断是否队列满
while (m_queue.count() > m_nQueue_Max_Size)
{
//等待信号触发,阻塞在此处。此时会释放m_Queue_Mutex锁,
//其他线程可以获取m_Queue_Mutex
m_Queue_Not_Full.wait(lock);
}
m_queue.enqueue(str);
m_Queue_Not_Empty.notify_all();
lock.unlock(); //释放锁,也可以不调用,最后函数返回时也会释放
}
QString Repository::GetData()
{
std::unique_lock<std::mutex> lock(m_Queue_Mutex);
//判断是否队列满
while (m_queue.isEmpty())
{
//等待信号触发,阻塞在此处。此时会释放m_Queue_Mutex锁,
//其他线程可以获取m_Queue_Mutex
m_Queue_Not_Empty.wait(lock);
}
QString str = m_queue.dequeue(); //获取数据
m_Queue_Not_Full.notify_all();
lock.unlock(); //释放锁,也可以不调用,最后函数返回时也会释放
return str;
}