Multithreading: Destructor wird nicht aufgerufen?wie warten?

Alles rund um die Programmierung mit Qt
Antworten
pioupus
Beiträge: 1
Registriert: 2. Juni 2011 06:23

Multithreading: Destructor wird nicht aufgerufen?wie warten?

Beitrag von pioupus »

Hi,
eine Frage:

Ich bin gerade dabei ein Programm mit 2 Threads zu schreiben: Dem GUI-Thread und einem Thread, der sich um das ansteuern von Hardware kümmert. Dabei wird dieser Thread von einer Klasse(THWDriver) gekapselt. Dessen Konstruktor startet das Thread working Objekt (THWDriverThread:QObject), um es mittels movetoThread in einen QThread zu transferieren:

Code: Alles auswählen

THWDriver::THWDriver()
{    
		HWDriverObject = new THWDriverThread();
    HWDriverThread = new QThreadEx();

		connect(HWDriverObject,SIGNAL(hwdtSigGotTemperature(THWTempSensorID , float ,bool)),
    	this,SLOT (hwdSloGotTemperature(THWTempSensorID , float ,bool)),Qt::QueuedConnection); //und viele mehr
    
		HWDriverObject->moveToThread(HWDriverThread);
    HWDriverThread->start();
}

THWDriver::~THWDriver(){
    HWDriverObject->deleteLater();
    HWDriverThread->deleteLater();
    HWDriverThread->quit();
}


THWDriverThread::THWDriverThread()
{
    QMetaObject::invokeMethod(this,
    	"init",
      Qt::QueuedConnection);//a "hack" for making all objects beeing always in this thread
}

void THWDriverThread::init(){
    serial = new AbstractSerial(this);
		wrapper = new Wrapper();
}

void THWDriverThread::CloseEverythingForLeaving(){
    if (wrapper)
        wrapper->closeAllSpectrometers();
    delete wrapper;
    wrapper = NULL;
    if (serial)
        serial->close();
    delete serial;
    serial = NULL;
}

THWDriverThread::~THWDriverThread(){
    CloseEverythingForLeaving();
}

Hinter dem Objekt Wrapper steht ein Treiber, der mit einem JAVA Programm arbeitet. Er startet scheinbar 10 weitere Threads.
Jetzt beginnen die Probleme: wenn ich mein Programm schließe, also ~THWDriver mit

Code: Alles auswählen

delete hwdriver
aufrufe, wird ~THWDriverThread nicht aufgerufen! Das ist blöd, da das Device nicht geschlossen wird und es beim nächsten Programmstart nicht mehr zur Verfügung steht. Wenn ich allerdings alle Wrapper-Zeilen auskommentiere, wird der Destructor aufgerufen.
Wenn ich CloseEverythingForLeaving manuell vor dem Schließen des Programms mit einem Signal von einem Button aufrufe, funktioniert auch alles.

Also meine Frage:
Mache ich etwas systematisch falsch mit der Threadkonstruktion oder Destruktion?
Gibt es eine Möglichkeit, das Schließem des GUI-Threads zu verzögern, sodass ich in aller Ruhe den CloseEverythingForLeaving Slot aufrufen kann?


Viele Grüße,
Arne
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

QThread aus der Eventloop rauslassen (wie Du das machst hängt von dir ab) und warten bis isFinished() true ist. Ich löse das meistens so dass das finsihed() - Signal deleteLater() aufruft. Zweite Möglichkeit: ich rufe deleteLater() direkt in run() nach exec() auf.
Der Hack im ctor von THWDriverThread ist unnötig - einfach die Objekte in run() instanziieren und selbst exec() aufrufen.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Antworten