¿Cómo puedo despertar un QThread cuando está durmiendo?¿Despertar un QThread que está en reposo?
Tengo un hilo que se ejecuta en el fondo y de vez en cuando se despierta y hace algunas cosas pequeñas, sin embargo, si me gustaría detener ese hilo de forma controlada, tengo que esperar a que se despierte por él auto para hacerlo renunciar. Y dado que está durmiendo bastante tiempo, esto puede ser bastante molesto.
Aquí hay un pequeño código de ejemplo que muestra el problema básico.
Comencemos con el hilo que en este ejemplo duerme durante 5 segundos y luego solo imprime un punto.
#include <QDebug>
#include "TestThread.h"
void TestThread::run()
{
running = true;
while(running == true)
{
qDebug() << ".";
QThread::sleep(5);
}
qDebug() << "Exit";
}
void TestThread::stop()
{
running = false;
}
Luego tenemos el principal que inicia el hilo y luego lo mata.
#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;
}
El problema es que tt-> wait(); debe esperar los 5 segundos para que el hilo duerma. ¿Puedo llamar algo así como un "despertar del sueño" para que pueda continuar?
¿O hay una manera mejor de hacer esto?
/Gracias
actualización lo tengo trabajando con un QMutex y la 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();
}
Pero sería mejor utilizar el QWaitCondition? ¿O es lo mismo?
actualización: Los descansos QMutex si no es la misma banda de rodamiento que se inicia y lo detiene, asi que aquí hay una oportunidad con 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();
}
Suena bien, pero ¿qué quieres decir? – Johan
Mira el ejemplo que he vinculado. La idea es bloquear un mutex y usar la función 'wait (QMutex *, long)' de la condición de espera para reemplazar su suspensión, y usar 'wakeAll()' o 'wakeOne()' en su función 'stop()'. Su edición no es buena: no debe llamar 'lock()' desde un hilo y 'unlock()' desde otro en el mismo objeto mutex. – Mat
Entonces nunca lo desbloqueas? ¿Mantiene el "bool funcionando" así que detenga el ciclo? – Johan