QThread (moveToThread) einfaches Verständnis Problem

Alles rund um die Programmierung mit Qt
Antworten
Anenja
Beiträge: 1
Registriert: 14. Februar 2013 19:33

QThread (moveToThread) einfaches Verständnis Problem

Beitrag von Anenja »

Hallo zusammen,

ich habe ein Verständnis Problem bei der Anwendung von QThreads.

Vorweg: ich hab ein, wie ich finde informatives youtube video zum Thema QT- Multithreading gefunden. (Ist von Dario Freddi bzw er macht die Präsentation im Video )
http://www.youtube.com/watch?v=MMFhc2jXzgw

Unteranderem habe ich aus dem obigen Video und nach einigen Recherchen herausgefunden, dass es seit QT 4.4 nicht mehr so sinvoll sein kann, QThread zu subclassen, daher habe ich versucht mal ein Beispielprogramm mit "moveToThread". (Gründe fuer diese Aussage werden unter anderem in dem obigen Video link genannt)

Einfaches Szenario dennoch ein Verständnis Problem :(

kurze Uebersicht ueber die Testklasse (nonsense Klasse, aber ich würde es gerne verstehen)
  • 1. Gui Widget mit einem Button -> on clicked() -> create worker1
    2. Worker1 erstellt im cTor Worker 2 und wartet auf das finished signal() von worker2
    3. Wenn Worker2 fertig ist, wird eventQueue von Worker1 interrupted
QWidget:

Code: Alles auswählen

void Widget::on_btTest_clicked()
{
    QTime time;
    time.start();
    worker1 *worker = new worker1;
    worker->doWork1();
    qDebug() << time.elapsed() << "mseconds" << "current time:" << time.currentTime().toString("hh:mm:ss:z")<< "worker1 result" << worker->getRes();
}
worker1:

Code: Alles auswählen

worker1::worker1(QObject *parent) :
    QObject(parent),
    m_classThread(new QThread),
    m_resultString("Hallo")
{
    moveToThread(m_classThread);
    m_worker2 = new Worker2;
    //breaks the own event loop if worker 2 is finished
    connect(m_worker2, SIGNAL(workDone()), &wait, SLOT(quit()));
    connect(this, SIGNAL(startNow()), m_worker2, SLOT(doWork2()));
    m_classThread->start();
}

void worker1::doWork1()
{
    //starts worker2 und wartet auf sein finished
    qDebug() << Q_FUNC_INFO;
    emit startNow();
    wait.exec();
}

QString worker1::getRes()
{
    return m_resultString;
}
Worker2:

Code: Alles auswählen

Worker2::Worker2(QObject *parent) :
    QObject(parent),
    m_classThread(new QThread),
    m_resultString("123")
{
    moveToThread(m_classThread);
    tima.setInterval(5000);
    tima.start();
    m_classThread->start();
}

void Worker2::doWork2()
{
    qDebug() << Q_FUNC_INFO;
    // create a event loop for the timer to be finished
    QEventLoop wait;
    connect(&tima, SIGNAL(timeout()), &wait, SLOT(quit()));
    wait.exec();
    emit workDone();

}
Wenn ich nun 2 mal hintereinander den Button clicke 2-3 sec verzögert. Bekomm das untenstehenden Ergebnis.

Ausgabe der Anwendung:

Code: Alles auswählen

void worker1::doWork1() 
void Worker2::doWork2() 
void worker1::doWork1() 
void Worker2::doWork2() 
5003 mseconds current time: "15:35:22:36" WIDGET: worker one "Hallo" 
7204 mseconds current time: "15:35:22:36" WIDGET: worker one "Hallo" 
Und genau hier beginnt mein Verständnisproblem. Bitte korregieren falls ich was falsches behaupte/verstanden habe.
Das glaube ich zu tun:
Ich erzeuge im QWidget(thread = Mainthread), das WorkerObjekt -> per cTor schiebe ich es in einen eingenen Thread. daraufhin erzeuge ich Worker 2 im Worker1 Thread und schiebe es im cTor von Worker2 in seinen eigenen Thread.
Nun würde es mich interessieren, warum das Ergebnis der Ausgabe "Zeitgleich" eintrifft? Müsste nicht der 1click auf den Button 2Sekunden vorher in der Debug ausgabe erscheinen?

Code: Alles auswählen

 worker->getRes(); 
Wenn ich vermuten darf, dann wuerde ich behaupten, dass das Problem darin besteht, dass die queue des Widgets erst abgearbeitet wird wenn die Worker fertig sind. Der Aufruf von worker->getRes(), erfolgt erst nachdem alle worker fertig sind -> Eventqueue des Mainthreads zum Zuge kommt?

Ich bin mir nicht sicher ob das so stimmt was ich geschrieben habe, Aber für ne Erklärung und ein Tipp wie man es besser/richtig lösen kann wäre ich euch dankbar.

Grüße!
Antworten