QThread (moveToThread) einfaches Verständnis Problem
Verfasst: 23. Februar 2013 15:52
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.
st 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)
worker1:
Worker2:
Wenn ich nun 2 mal hintereinander den Button clicke 2-3 sec verzögert. Bekomm das untenstehenden Ergebnis.
Ausgabe der Anwendung:
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?
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!
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.
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
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();
}
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;
}
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();
}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" 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(); 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!