唤醒处于睡眠状态的QThread?

时间:2011-07-15 10:03:33

标签: c++ qt qthread

如何在睡眠时唤醒QThread?

我有一个在后台运行的线程然后醒来并做一些小事情,但是如果我想以受控方式停止该线程,我必须等待他自己醒来为了让他退出。而且由于他睡得很久,这可能会非常烦人。

这是一个显示基本问题的示例代码。

让我们从这个例子中休眠5秒然后只打印一个点的线程开始。

#include <QDebug>
#include "TestThread.h"

void TestThread::run()
{
    running = true;
    while(running == true)
    {
        qDebug() << ".";
        QThread::sleep(5);
    }
    qDebug() << "Exit";
}

void TestThread::stop()
{
    running = false;
}

然后我们有了启动线程然后杀死他的主。

#include <QDebug>
#include "TestThread.h"

int main(int argc, char *argv[])
{
    qDebug() << "Start test:";
    TestThread *tt = new TestThread();

    tt->start();
    sleep(2);
    tt->stop();
    tt->wait();

    delete tt;    
}

问题是tt-&gt; wait();必须等待线程正在睡觉的5s。 我可以称之为“从睡眠中醒来”,这样他就可以继续。

或者有更好的方法吗?

/感谢


更新我使用了QMutex和tryLock:

#include <QDebug>
#include "TestThread.h"

QMutex sleepMutex; 

void TestThread::run()
{
    qDebug() << "Begin";
    //1. Start to lock
    sleepMutex.lock(); 
    //2. Then since it is locked, we can't lock it again
    //   so we timeout now and then.
    while( !sleepMutex.tryLock(5000) )
    {
        qDebug() << ".";
    }
    //4. And then we cleanup and unlock the lock from tryLock.
    sleepMutex.unlock();
    qDebug() << "Exit";
}

void TestThread::stop()
{
    //3. Then we unlock and allow the tryLock 
    //   to lock it and doing so return true to the while 
    //   so it stops.
    sleepMutex.unlock();
}

但使用QWaitCondition会更好吗?或者它是一样的吗?


更新:如果启动和停止他的QMutex不同,QMutex就会中断, 所以这是QWaitCondition的尝试。

#include <QDebug>
#include <QWaitCondition>
#include "TestThread.h"

QMutex sleepMutex; 

void TestThread::run()
{
    qDebug() << "Begin";

    running = true;
    sleepMutex.lock(); 
    while( !waitcondition.wait(&sleepMutex, 5000) && running == true )
    {
        qDebug() << ".";
    }
    qDebug() << "Exit";
}

void TestThread::stop()
{
    running = false;
    waitcondition.wakeAll();
}

2 个答案:

答案 0 :(得分:6)

您可以使用QWaitCondition而不是简单的sleep。如果给你更多的控制权。

此处使用示例:Wait Conditions Example

答案 1 :(得分:1)

我认为不存在便携式解决方案(尽管在某些操作系统中可能存在某些设施,例如POSIX信号)。无论如何,Qt本身并没有提供这样的手段,因此你可以像

那样模拟它
void TestThread::run()
{
    running = true;
    while(running == true)
    {
        qDebug() << ".";
        // Quantize the sleep:
        for (int i = 0; i < 5 && running; ++i) QThread::sleep(1);
    }
    qDebug() << "Exit";
}

但最好的解决方案仍然是QWaitCondition,正如Mat所指出的那样。