开发者

Wake up a QThread that is in sleep?

开发者 https://www.devze.com 2023-03-20 17:57 出处:网络
How can I wake up a QThread when it is sleeping? 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

How can I wake up a QThread when it is sleeping?

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.

#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.

#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(); must wait the 5s that the thread is sleeping. 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:

#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? 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.

#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. 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). Anyway, Qt itself doesn't provide such means, thus you could simulate it like

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消