Boucles d'événements et traitement des emplacements de signaux lors de l'utilisation du multithreading dans Qt

J'ai eu quelques problèmes avec l'aide de QThreads qui m'a fait découvrir différentes combinaisons avant, j'ai trouvé le droit. Cependant je n'ai toujours pas bien comprendre ce qui se passe vraiment dans les quatre cas illustré ci-dessous lorsqu'il s'agit d'une boucle d'événement et signal-slot de traitement.

J'ai ajouté quelques commentaires à la section de SORTIE, mais comme vous pouvez le voir je ne suis pas sûr si mes hypothèses sur les causes de comportements observés sont corrects. Aussi je ne suis pas sûr si case 3 est quelque chose qui pourrait être utilisée dans le code réel. Voici mon code de test (uniquement le main.cpp diffère pour chaque cas):

travailleur.h:

#include <QObject>
#include <QDebug>
#include <QThread>

class Worker : public QObject
{
    Q_OBJECT
public:
    explicit Worker(QObject *parent = 0) { this->isRunning_ = false;}
    bool isRunning() const { return isRunning_; }

signals:
    void processingFinished();
    void inProgress();

public slots:
    void process()
    {
        this->isRunning_ = true;
        qDebug() << this << "processing started";
        for (int i = 0; i < 5; i++)
        {
            QThread::usleep(1000);
            emit this->inProgress();
        }
        qDebug() << this << "processing finished";
        this->isRunning_ = false;
        emit this->processingFinished();
    }

private:
    bool isRunning_;
};

workermanager.h:

#include "worker.h"

class WorkerManager : public QObject
{
    Q_OBJECT
public:
    explicit WorkerManager(QObject *parent = 0) :
        QObject(parent) {}

public slots:
    void process()
    {
        QThread *thread = new QThread();
        Worker  *worker = new Worker();

        connect(thread,SIGNAL(started()),worker,SLOT(process()));
        connect(worker,SIGNAL(processingFinished()),this,SLOT(slot1()));
        connect(worker,SIGNAL(inProgress()),this,SLOT(slot2()));
        worker->moveToThread(thread);

        qDebug() << "starting";
        thread->start();
        QThread::usleep(500);
        while(worker->isRunning()) { }
        qDebug() << "finished";
    }

    void slot1() { qDebug() << "slot1"; }
    void slot2() { qDebug() << "slot2"; }
};

main.cpp (cas 1 - pas de thread séparé pour workerManager):

#include <QCoreApplication>
#include "workermanager.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    WorkerManager* workerManager = new WorkerManager;    
    workerManager->process();
    qDebug() << "end";
    return a.exec();
}

De SORTIE - deux slot1 et slot2 appelé à a.exec() (??? - à l'aide de boucle principale?):

starting 
Worker(0x112db20) processing started 
Worker(0x112db20) processing finished 
finished 
end
slot2 
slot2 
slot2 
slot2 
slot2 
slot1 

main.cpp (cas 2 - workerManager déplacé vers thread séparé, mais thread a pas démarré):

#include <QCoreApplication>
#include "workermanager.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    WorkerManager* workerManager = new WorkerManager;
    QThread *thread = new QThread();   
    workerManager->moveToThread(thread);       
    workerManager->process();
    qDebug() << "end";
    return a.exec();
}

De SORTIE ni slot1 ni slot2 a été appelé - (??? boucle d'événement associé avec thread reçoit des signaux, mais depuis le thread n'a pas commencé à fentes ne sont pas appelés?):

starting 
Worker(0x112db20) processing started 
Worker(0x112db20) processing finished 
finished 
end

main.cpp (cas 3 - workerManager déménagé à autre thread, le thread a commencé, mais workerManager::process() appelé via workerManager->process()):

#include <QCoreApplication>
#include "workermanager.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    WorkerManager* workerManager = new WorkerManager;
    QThread *thread = new QThread();   
    workerManager->moveToThread(thread); 
    thread->start();     
    workerManager->process();
    qDebug() << "end";
    return a.exec();
}

De SORTIE - slot2 appelé alors que Worker encore de l'exécution de son process() (???):

starting 
Worker(0x197bb20) processing started 
slot2 
slot2 
slot2 
slot2 
Worker(0x197bb20) processing finished 
finished 
end 
slot2 
slot1 

main.cpp (cas 4 - workerManager déménagé à autre thread, le thread a commencé, mais workerManager::process() appelé à l'aide started() signal de thread):

#include <QCoreApplication>
#include "workermanager.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    WorkerManager* workerManager = new WorkerManager;
    QThread *thread = new QThread();    
    workerManager->moveToThread(thread);
    QObject::connect(thread,SIGNAL(started()),workerManager,SLOT(process()));
    thread->start();
    qDebug() << "end";
    return a.exec();
}

De SORTIE - tous les événements traités après avoir atteint a.exec() (???):

end 
starting 
Worker(0x7f1d700013d0) processing started 
Worker(0x7f1d700013d0) processing finished 
finished 
slot2 
slot2 
slot2 
slot2 
slot2 
slot1 

Merci pour les précisions.

source d'informationauteur Moomin | 2015-01-20