问题:为解决控制台程序日志界面打印管理服务器日志功能,我自己写了一个线程,采用队列的形式,但是对于什么时候发来日志,什么时候写日志,日志线程sleep多长时间,都不确定,而不sleep的话,线程若没有任务时就处于空转状态任务多时,频繁向日志界面增加日志,又会导致界面卡。
解决方案:在打印日志线程中,使用一个QWaitCondition。QWaitCondition提供了一个等待的条件。它允许一个线程告诉其他线程某个条件被满足了。从而其他线程开始执行任务。其他线程可以通过调用QWaitCondition的wait函数来阻塞自己,来等待某个条件,条件满足则线程开始执行,否则继续等待。等待的条件是锁。
这样,当加入任务时,线程就转一圈。没有加入任务时,线程就一直在等待,等待加入任务。从而就可以保证线程不空转,也可以保证能够及时的响应任务,执行任务。
代码如下:
QWaitCondition m_hasNewLog;
QMutex m_mutex;
QQueue m_logQueue;
void WriteLogThread::run()
{
while(!m_bStop)
{
m_mutex.lock();
m_hasNewLog.wait(&m_mutex);
while(m_logQueue.size()> 0)
{
QString tempLog = m_logQueue.dequeue();
emit sigWriteLog(tempLog);
}
m_mutex.unlock();
}
}
void WriteLogThread::insertLog(QStringlogStr)
{
m_mutex.lock();
m_logQueue.push_back(logStr);
m_hasNewLog.wakeAll();
m_mutex.unlock();
}
void WriteLogThread::stop()
{
m_mutex.lock();
m_bStop= true;
m_mutex.unlock();
}
此处,线程退出时,进行一次加锁,让线程转一下,并且把停止线程的变量m_bStop置为true,下一次循环时,循环条件不符合,线程退出。
详细的用法可以查看QT文档对QWaitCondition的介绍。