QThreads und static-Objekte
Verfasst: 11. Dezember 2008 15:07
Hallo,
ich habe vermutlich ein Problem mit o.g. Objekten. Folgendes Szenario: In meiner App-Klasse installiere ich einen Message-Handler für Debug-Messages, dessen Funktion eine Funktion in einem statischen Klassen-Member aufruft:
App.hpp:
In der Implementierungsdatei definiere ich dann das statische Log-Objekt und die Funktion für den Message-Handler:
Im Konstruktor von App setze ich den MsgHandler:
Soweit so gut. In der App werden aber noch jede Menge andere Objekte initialisiert und ans Laufen gebracht, u.a. mehrere von QThread abgeleitete Objekte, die bis zum Beenden des Programms durchlaufen:
Engine.cpp
Soweit so gut. Wenn das Programm beendet wird, wird der Destruktor der App aufgerufen und der Thread beendet:
Das Problem ist, dass wenn die App sich beendet der Thread ja noch laufen kann, bis er sich beendet, wird ja mit wait() vorgegeben, d.h. er wartet 50 ms darauf, das dir run()-Methode terminiert. Leider bekomme ich eine Exception, wenn sich das Programm beendet, und ich vermute, dass sich das statische mLog-Objekt schon zerstört hat, während der Thread immer noch läuft. Meines Wissens werden statische Objekte zerstört, nachdem sich main() beendet hat.
Deshalb meine Frage: Können QThreads noch laufen, wenn sich main() (im Hauptthread) beendet hat?
Wenn ja: Wie kann man das verhindern ?
Nachtrag: Ein Test mit qDebug()'s am Ende des App::~App Destruktors zeigt, dass danach noch jede Menge Debug-Meldungen aus den Thread(s) kommen, d.h. sie laufen wohl auch noch, wenn schon das QApp-Objekt zerstört wurde.
Bin für alle Tipps dankbar,
AlGaN
ich habe vermutlich ein Problem mit o.g. Objekten. Folgendes Szenario: In meiner App-Klasse installiere ich einen Message-Handler für Debug-Messages, dessen Funktion eine Funktion in einem statischen Klassen-Member aufruft:
App.hpp:
Code: Alles auswählen
class App : public QApplication
{
Q_OBJECT
public:
App( int argc, char* argv[]);
~App();
static Log::LogMessage log( Log::LogLevel, QString msg );
[...]
private:
static void qt_msg_handler( QtMsgType type, const char* msg);
static Log mLog;
Engine* mEngine;
[...]
};
Code: Alles auswählen
[...]
/* static member variables */
Log App::mLog;
void App::qt_msg_handler( QtMsgType type, const char* s)
{
QString msg(s);
switch (type)
{
case QtDebugMsg:
mLog.log( "QtDebugMsg: %1").arg( msg );
break;
[...]
}
Code: Alles auswählen
App:App(int argc, char* argv[])
{
// install qt debug handler
qInstallMsgHandler( qt_msg_handler );
[...]
// construct Engine thread
mEngine = new Engine( this );
[...]
mEngine->start();
}
Code: Alles auswählen
class Engine: public QThread
{
Q_OBJECT
public:
Engine( QObject *parent );
~Engine();
protected:
virtual void run();
virtual void stop();
[...]
};
Code: Alles auswählen
Engine::Engine( QObject* parent )
: QThread( parent )
{
[...]
start();
}
Engine::~Engine()
{
qDebug() << "Stopping Engine"; // <-- Fehler ??
stop();
[...]
}
void Engine::stop()
{
mRunningLock.lock();
mRunning = false;
mRunning.unlock();
if ( !wait( 50 ) )
{
qDebug() << "Thread hangs! this should never happen!";
}
}
Code: Alles auswählen
App:~App()
{
mEngine->stop();
[...]
}
Deshalb meine Frage: Können QThreads noch laufen, wenn sich main() (im Hauptthread) beendet hat?
Wenn ja: Wie kann man das verhindern ?
Nachtrag: Ein Test mit qDebug()'s am Ende des App::~App Destruktors zeigt, dass danach noch jede Menge Debug-Meldungen aus den Thread(s) kommen, d.h. sie laufen wohl auch noch, wenn schon das QApp-Objekt zerstört wurde.
Bin für alle Tipps dankbar,
AlGaN