简体   繁体   English

唤醒一个处于睡眠状态的 QThread?

[英]Wake up a QThread that is in sleep?

How can I wake up a QThread when it is sleeping?如何在 QThread 处于睡眠状态时唤醒它?

I have a thread that is running in the background and now and then wakes up and does some small stuff, however if I would like to stop that thread in a controlled manner I have to wait for him to wake up by him self in order to make him quit.我有一个在后台运行的线程,然后不时醒来并做一些小事情,但是如果我想以受控方式停止该线程,我必须等待他自己醒来才能让他退出。 And since he is sleeping quite long this can be quite annoying.而且由于他睡了很长时间,这可能很烦人。

Here is a little example code that show the basic problem.这是一个显示基本问题的小示例代码。

Let's start with the thread that in this example sleeps for 5 seconds and then just prints a dot.让我们从这个例子中休眠 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;
}

Then we have the main that starts the thread and then kills him.然后我们有 main 启动线程然后杀死他。

#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;    
}

The problem is that the tt->wait();问题是 tt->wait(); must wait the 5s that the thread is sleeping.必须等待线程休眠的 5 秒。 Can I just call something like a "wakeup from sleep" so he can continue.我可以叫一个像“从睡眠中醒来”这样的东西,这样他就可以继续了。

Or is there a better way to do this?还是有更好的方法来做到这一点?

/Thanks /谢谢


Update I got it working with a QMutex and the tryLock:更新我让它与 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();
}

But would it be better to use the QWaitCondition?但是使用 QWaitCondition 会更好吗? Or is it the same?还是一样?


Update : The QMutex breaks if it is not the same tread that starts and stop him, so here is a try with QWaitCondition.更新:如果启动和停止他的胎面不同,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();
}

You could use a QWaitCondition rather than a simple sleep .您可以使用QWaitCondition而不是简单的sleep If gives you much more control.如果给你更多的控制权。

Example usage here: Wait Conditions Example此处的示例用法:等待条件示例

I don't think that a portable solution exists (though there might be some facilities in some operation systems, like POSIX signals).我认为不存在可移植的解决方案(尽管某些操作系统中可能有一些设施,例如 POSIX 信号)。 Anyway, Qt itself doesn't provide such means, thus you could simulate it like无论如何, 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";
}

But the best solution would still be a QWaitCondition, as pointed out by Mat.但正如 Mat 所指出的,最好的解决方案仍然是 QWaitCondition。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM