QThread.terminate() Problem unter Linux, Signale löschen
Verfasst: 27. November 2008 10:58
Hallo,
Ich habe folgendes Problem, in meiner GUI habe ich einen QThread erzeugt, der im Hintergrund diverse berechnungen durchführt. Wenn auf der GUI der "Abort" Button gedrückt wird soll dieser Thread abgeschossen werden. Da ich in dem Thread keinerlei Mutexe oder ähnliches verwende geht das ganz gut indem ich einfach: meinThread.terminate() mache. Das ganze klappt unter Windows wunderbar. Da die Software aber auch unter Linux laufen soll habe ich das da natürlich auch getestet und da steigt die Software komplett mit einen Fehler komplett aus (Fatal exception not rethrown). Okay es musste eine andere lösung her, da selbst wenn ich in meinem Thread die Exception weitergebe (mit throw) schmiert es ab (hab da schon diverse sachen probiert, falls jemand eine Idee haben sollte wie ich das doch noch in den Griff bekommen, gerne her damit
)
In meinem Thread ist jetzt einfach ein boolsches abbruchkriterium das aus den run() aussteigt, lieder habe ich da bis zu 3 sekunden abbruchzeit, bis dieses Kriterium wieder getestet werden kann. Deshalb habe ich folgende (mMn recht abenteuerliche Konstruktion):
Das ganze Problem ist, wenn ein User mal wieder anstatt einmal auf abort zu klicken, mehrfach drauf hämmert (die Gui sollte möglichst DAU sicher sein, deswegen ist das leider auch ein use case
), wird das Signal clicked() vom Button trotzdem ausgelößt obwohl es während des blockierenden wait eigendlich disabled ist.
Scheinbar werden alle Singale in einer Art Queue abgelegt, wenn ein blockierender Aufruf in der GUI stattfindet (mStitchThread->wait(); in meinem Fall) und dann abgearbeitet, wenn wieder Zeit ist (in dem Fall wenn die Funktion verlassen wurde). Zu dem Zeitppunkt ist der Button ja wieder enabled... Was zu einem schnellen Wechsel von run/abort führt... wobei der abort wie gesagt wieder 2-3 Sekunden dauert ...
Gibt es irgendeine Möglichkeit am ende des blockes alle bereits ausgelößten signale die in der "Queue" sind zu löschen? Ich dachte eigendlich dass das durch das blocken von den Signalen funktioniert, tut es aber leider nicht.
Ich hoffe mal ich konnte mein Problem einigermaßen verständlich machen.
Danke schon mal im Vorraus, Streen
Ich habe folgendes Problem, in meiner GUI habe ich einen QThread erzeugt, der im Hintergrund diverse berechnungen durchführt. Wenn auf der GUI der "Abort" Button gedrückt wird soll dieser Thread abgeschossen werden. Da ich in dem Thread keinerlei Mutexe oder ähnliches verwende geht das ganz gut indem ich einfach: meinThread.terminate() mache. Das ganze klappt unter Windows wunderbar. Da die Software aber auch unter Linux laufen soll habe ich das da natürlich auch getestet und da steigt die Software komplett mit einen Fehler komplett aus (Fatal exception not rethrown). Okay es musste eine andere lösung her, da selbst wenn ich in meinem Thread die Exception weitergebe (mit throw) schmiert es ab (hab da schon diverse sachen probiert, falls jemand eine Idee haben sollte wie ich das doch noch in den Griff bekommen, gerne her damit
In meinem Thread ist jetzt einfach ein boolsches abbruchkriterium das aus den run() aussteigt, lieder habe ich da bis zu 3 sekunden abbruchzeit, bis dieses Kriterium wieder getestet werden kann. Deshalb habe ich folgende (mMn recht abenteuerliche Konstruktion):
Das ganze Problem ist, wenn ein User mal wieder anstatt einmal auf abort zu klicken, mehrfach drauf hämmert (die Gui sollte möglichst DAU sicher sein, deswegen ist das leider auch ein use case
Scheinbar werden alle Singale in einer Art Queue abgelegt, wenn ein blockierender Aufruf in der GUI stattfindet (mStitchThread->wait(); in meinem Fall) und dann abgearbeitet, wenn wieder Zeit ist (in dem Fall wenn die Funktion verlassen wurde). Zu dem Zeitppunkt ist der Button ja wieder enabled... Was zu einem schnellen Wechsel von run/abort führt... wobei der abort wie gesagt wieder 2-3 Sekunden dauert ...
Gibt es irgendeine Möglichkeit am ende des blockes alle bereits ausgelößten signale die in der "Queue" sind zu löschen? Ich dachte eigendlich dass das durch das blocken von den Signalen funktioniert, tut es aber leider nicht.
Ich hoffe mal ich konnte mein Problem einigermaßen verständlich machen.
Danke schon mal im Vorraus, Streen
Code: Alles auswählen
if (mStitchThread->isRunning())
{
emit updateStatus("Aborting... please wait.");
// disable all items
mParent->setEnabled(false);
// disconnect the signals
this->unregisterSignalSlot();
// block all signals during aborting
mParent->blockSignals(true);
// force repaint
mParent->update();
mParent->repaint();
// Abort the thread
mStitchThread->abort(); // abort variable wird hier gesetzt
mStitchThread->wait();
// re register the signals and slots
this->registerSignalSlot();
mParent->setEnabled(true);
// rename the button
emit updateStatus("Run has been aborted.");
mRunButton->setText("Run");
mParent->blockSignals(false);
}
else
{
// pass the settings to the Thread
mStitchThread->setImagePath (mInputPathLineEdit->text());
// then start the thread
mStitchThread->start();
// rename the button
mRunButton->setText("Abort");
}