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

Posted

技术标签:

【中文标题】唤醒一个处于睡眠状态的 QThread?【英文标题】:Wake up a QThread that is in sleep? 【发布时间】:2011-10-06 00:48:16 【问题描述】:

如何在 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;

然后我们有 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;    

问题在于 tt->wait();必须等待线程休眠的 5 秒。 我可以叫一个“从睡眠中唤醒”之类的东西,这样他就可以继续了。

或者有更好的方法吗?

/谢谢


更新我让它与 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 就会中断, 所以这里是 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();

【问题讨论】:

【参考方案1】:

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

此处的用法示例:Wait Conditions Example

【讨论】:

看我链接的例子。这个想法是锁定一个互斥锁并使用等待条件的wait(QMutex*,long) 函数来替换您的睡眠,并在您的stop() 函数中使用wakeAll()wakeOne()。你的编辑不好:你不应该在同一个互斥对象上从一个线程调用lock(),从另一个线程调用unlock() 所以你从来没有解锁过他?你保持“布尔运行”所以停止循环?【参考方案2】:

我认为不存在可移植的解决方案(尽管某些操作系统中可能有一些设施,例如 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";

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

【讨论】:

以上是关于唤醒一个处于睡眠状态的 QThread?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 Mac 置入睡眠状态或唤醒 Mac?

从睡眠模式唤醒时不会播放音频(android)

使用信号从睡眠中唤醒进程

电脑在睡眠状态下能远程吗?能否在远程进行登入唤醒。。

如果设备已被唤醒或进入睡眠状态,如何检查应用程序

通过声音将设备从睡眠中唤醒的 iPhone 闹钟