Wake up QThread, which is in a dream?

How can I wake QThread when it sleeps?

I have a thread that runs in the background and wakes up from time to time and does some small things, however, if I want to stop this thread in a controlled way, I have to wait for it to wake up itself to make it leave. And since he sleeps quite a while, this can be very unpleasant.

Here is a small sample code that shows the main problem.

Start with the thread, which 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 thing that the flow begins, and then kills it.

 #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 tt-> wait (); should wait 5 seconds for the thread to sleep. Can I just call something like “awakening from sleep” so that it can continue.

Or is there a better way to do this?

/Thanks


Update . I worked with QMutex and 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 QWaitCondition? Or is it the same thing?


Update : QMutex breaks if it is not the same tread that starts and stops it, so here is an attempt 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(); } 
+7
source share
2 answers

You can use QWaitCondition , rather than simple sleep . If you get a lot more control.

Usage example here: Waiting conditions example

+6
source

I do not think there is a portable solution (although some operating systems may have some features, such as POSIX signals). In any case, Qt itself does not provide such tools, so you can simulate it as

 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 be QWaitCondition, as stated in Mat.

+1
source

All Articles