Ho pensato molto e letto molti articoli prima di fare questa domanda qui. Nessuno degli articoli mi ha dato una risposta adeguata.QThread finished() collegato a deletelater di un QObject
http://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/
QThread* thread = new QThread;
Worker* worker = new Worker();
worker->moveToThread(thread);
connect(worker, SIGNAL(error(QString)), this, SLOT(errorString(QString)));
connect(thread, SIGNAL(started()), worker, SLOT(process()));
connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();
oggetto lavoratore ha affinità del nuovo filo.
1> Il segnale del lavoratore finito chiamerà quit() sul thread. Questo interromperà il loop eventi del thread e avvia il segnale finito del thread.
2> Il segnale di lavoro finito è collegato al worker deleteLater(). Secondo la documentazione di deleteLater()
** Pianifica questo oggetto per la cancellazione. L'oggetto verrà cancellato quando il controllo ritorna al ciclo degli eventi. Se il ciclo degli eventi è> non è in esecuzione
quando questa funzione viene chiamata (ad esempio deleteLater() viene chiamato su un oggetto prima QCoreApplication :: exec()), l'oggetto verrà cancellato una volta avviato il ciclo di eventi.
Nota che entrare e uscire da un nuovo ciclo di eventi (ad esempio aprendo una finestra di dialogo modale) non eseguirà la cancellazione posticipata di ; per l'oggetto da eliminare, il controllo deve tornare al ciclo di eventi da cui è stato chiamato deleteLater().
Nota: It è possibile chiamare questa funzione più di una volta; quando il primo evento differita eliminazione viene consegnato, tutti gli eventi in corso per l'oggetto vengono rimossi dalla coda degli eventi. **
Così, quando non v'è alcuna eventloop, dal momento che il filo è già uscendo e che ha già sollevato il segnale finito e non avremo più riavviato lo stesso thread. In questo caso, deleteLater() non verrà mai gestito poiché il ciclo di eventi non esiste e l'oggetto di lavoro non verrà eliminato. Questo non crea una perdita di memoria?
connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
Se pensiamo che lo scambio delle due linee risolverà il problema, allora ho un'altra domanda. QT indica chiaramente che l'ordine di chiamata degli slot quando viene emesso un segnale è indeterminato
Ci sono molti commenti nel collegamento dell'articolo sopra menzionato. Anche l'autore non è stato in grado di rispondere alla domanda completamente
non puoi cancellare il lavoratore nel thread oggetto creato. poiché è già stato spostato nella discussione usando moveToThread. Puoi spiegare questo. – Srikan
Inoltre, consiglierei di assegnare un genitore a 'QThread'.Poiché l'istanza di 'QThread' è parte del thread in cui è stato generato (diversamente da qualsiasi oggetto che è stato spostato su di esso o il suo metodo' run() ') è perfettamente sicuro fare' thread = new QThread (this); 'if' thread' deve essere parte di qualche altra classe. In generale, dovresti evitare di chiamare 'delete' se esiste una soluzione non manuale migliore. Persino nel C++ standard ci sono dei puntatori intelligenti e ciò che non richiede l'eliminazione manuale delle spalle. – rbaleksandar