Utiliser QThread.

desire -  
 Pierre -
Bonjour,
je programme en Qt et je veut utiliser les threads pour gérer un problème de boucle qui dure vraiment.
j'ai lu la doc mais je m'en sort vraiment pas. aidez moi. voici le problème:

je veux utiliser par exemple la boucle suivante(qui chronomètre 50 secondes):

debut=clock();
while(1)
{
fin=clock();
if(fin-debut>50000) goto a;
}
a:

mais cela bloque le programme pendant longtemps.
comment dois je donc l'insérer avec un QThread pour le faire fonctionner paralelement avec le reste du programme?
merci pour toute reponse..........

2 réponses

Pierre
 
[Il "suffit" de créer une classe héritant de Qthread . Dans le constructeur de ta classe, tu fais d'abors commencer le constructeur de Qthread, puis tu continue normalement, comme si tu faisais une classe classique . Voici un exemple tiré de Qt Example : ]

Faux, attention à ne pas confondre la classe QThread et le contexte de thread associé.
Le constructeur d'un objet QThread (ou dérivé) est appelé depuis un thread bien spécifique: celui de l'objet appelant. Il ne s'execute donc en aucun cas dans un thread différent ! (de même pour le destructeur).

Donc si on écrit:


// Dans MyThread.h

class MyThread : public QThread
{
    public:

          MyThread(QObject* parent = NULL);
          virtual ~MyThread();
    ....

};

// Dans MyThread.cpp

MyThread::MyThread(QObject* parent):
QThread(parent)
{

     // instanciation objets de travail...

    ...

     // long traitement

}
MyThread::~MyThread()
{
     exit();
     wait();

     // nettoyage

}

int main(int argc, char** argv)
{
    QMyThread* newThread = new QMyThread();
    

    ....

    return;
}



Il faut bien comprendre que l'objet MyThread est crée dans le contexte du thread principal ! (celui de main).
Donc son constructeur est executé... dans le contexte du thread principal... et non dans un thread à part.

Pour utiliser le thread sous-jacent d'un objet QThread dérivé, il faut surdéfinir la méthode QThread::run() et placer le code à executer dedans (c'est la méthode run qui défini la portée du nouveau thread, ce thread démarre sa vie à l'entrée de run() et s'arrete en sortie)

On obtient donc par exemple:


// Dans MyThread.h

class MyThread : public QThread
{
    public:

          MyThread(QObject* parent = NULL);
          virtual ~MyThread();

    
     protected:
           virtual void run();
     
    ....

};

// Dans MyThread.cpp

MyThread::MyThread(QObject* parent):
QThread(parent)
{
        // start démarre effectivement le nouveau thread et appelle sa méthode run()
        start();
}
MyThread::~MyThread()
{
     exit();
     wait();

     // nettoyage

}

void MyThread::run()
{

       // long traitement effectué dans le thread crée
       ...
}




Si vous devez ensuite utiliser des connections signaux/slots entre threads, il faut que les objets communiquants soient rattachés aux threads effectifs, ils doivent donc être créés dans des contexte threads différents (dans MyThread::run() par exemple et dans main()) (on peut toujours créér un objet dans un contexte thread quelconque puis l'attacher à un autre thread ultérieurement en appelant moveToThread et en respectant certaines règles d'affinité/parenté, cf. QtAssistant)
9
kico
 
Il "suffit" de créer une classe héritant de Qthread . Dans le constructeur de ta classe, tu fais d'abors commencer le constructeur de Qthread, puis tu continue normalement, comme si tu faisais une classe classique . Voici un exemple tiré de Qt Example :

#include <QtGui>

#include <math.h>

#include "renderthread.h"

RenderThread::RenderThread(QObject *parent)

: QThread(parent) //comme tu vois, on commence par le constructeur de QThread, puis on continue
//notre fonction

{
restart = false;
abort = false;

for (int i = 0; i < ColormapSize; ++i)
colormap[i] = rgbFromWaveLength(380.0 + (i * 400.0 / ColormapSize));
}

RenderThread::~RenderThread()
{
mutex.lock();
abort = true;
condition.wakeOne();
mutex.unlock();

wait();
}


Après, il te suffit de créer la classe dans le thread principal, et voila !
Par contre, pour créer des connexions signal/slot entre threads, je te renvoi ici : https://matthieu-brucher.developpez.com/tutoriels/cpp/qt/signal-slot/
2