Comment puis-je réveiller un QThread lorsqu'il dort? J'ai un thread qui fonctionne en arrière-plan et qui se réveille de temps en temps et fait de petites choses, mais si je veux arrêter ce thread de manière contrôlée, je dois attendre qu'il se réveille par lui soi-même afin de le faire quitter. Et comme il dort assez longtemps, cela peut être assez ennuyeux.Réactiver un QThread en veille?
Voici un petit exemple de code qui montre le problème de base.
Commençons par le fil qui, dans cet exemple, dort pendant 5 secondes, puis imprime simplement un point. Ensuite, nous avons le principal qui démarre le thread et le tue. Ensuite, nous avons le principal qui démarre le thread.
#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;
}
Le problème est que le tt-> wait(); doit attendre les 5s que le fil dorme. Puis-je appeler quelque chose comme un "réveil de sommeil" afin qu'il puisse continuer.
Ou y a-t-il une meilleure façon de faire cela?
/Merci
Mise à jour Je l'ai travaillé avec un QMutex et 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();
}
Mais serait-il préférable d'utiliser le QWaitCondition? Ou est-ce le même?
Mise à jour: Les pauses QMutex si elle est pas la même bande de roulement qui commence et l'arrêter, alors voici est un essai avec 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();
}
Ça a l'air bien, mais comment voulez-vous dire? – Johan
Regardez l'exemple que j'ai lié. L'idée est de verrouiller un mutex et d'utiliser la fonction wait (wait (QMutex *, long)) pour remplacer votre sleep, et d'utiliser 'wakeAll()' ou 'wakeOne()' dans votre fonction 'stop()'. Votre édition n'est pas bonne: vous ne devriez pas appeler 'lock()' d'un thread et 'unlock()' d'un autre sur le même objet mutex. – Mat
Alors vous ne le débloquez jamais? Vous gardez le "bool running" alors arrêtez la boucle? – Johan