J'ai beaucoup réfléchi et lu beaucoup d'articles avant de poser cette question ici. Aucun des articles m'a donné une réponse appropriée.QThread terminé() connecté à deletelater d'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();
objet travailleur a l'affinité du nouveau fil.
1> Le signal de fin de travail appellera quit() sur le fil. Cela met fin à la boucle d'événement du thread et initie le signal terminé.
2> Le signal de fin de travail est connecté au worker deleteLater(). Selon la documentation deleteLater()
** Planifie la suppression de cet objet. L'objet sera supprimé lorsque le contrôle reviendra à la boucle d'événements. Si la boucle d'événement est> ne fonctionne pas
lorsque cette fonction est appelée (par exemple deleteLater() est appelée sur un objet avant QCoreApplication :: exec()), l'objet sera supprimé une fois que la boucle d'événements est démarré.
Notez que l'entrée et la sortie d'une nouvelle boucle d'événements (par exemple, en ouvrant une boîte de dialogue modale) n'effectueront pas la suppression différée ; Pour que l'objet soit supprimé, le contrôle doit retourner à la boucle d'événements à partir de laquelle deleteLater() a été appelé.
Remarque: est sûr d'appeler cette fonction plus d'une fois; lorsque le premier événement différé de suppression est livré, les événements en attente de l'objet sont retirés de la file d'attente. **
Alors, quand il n'y a pas eventloop, puisque le fil est sortie déjà et il a déjà soulevé le signal terminé et nous ne recommencerons plus le même fil. Dans ce cas, deleteLater() ne sera jamais manipulé car la boucle d'événement n'existe pas et l'objet worker ne sera pas supprimé du tout. Cela ne crée-t-il pas une fuite de mémoire? Si nous pensons que l'échange des deux lignes permettra de résoudre le problème, alors j'ai une autre question. QT indique clairement que l'ordre dans lequel les slots sont appelés lorsqu'un signal est émis est indéterminé.
Il y a beaucoup de commentaires dans le lien d'article mentionné ci-dessus. Même l'auteur n'a pas été en mesure de répondre à la question complètement
Vous ne pouvez pas supprimer le travailleur dans le thread d'objet créé. car il a déjà été déplacé vers le Thread en utilisant moveToThread. Pouvez-vous expliquer cela. – Srikan
Aussi, je conseillerais d'assigner un parent à 'QThread'.Puisque l'instance de QThread fait partie du thread où elle a été générée (contrairement à tous les objets qui y ont été déplacés ou à sa méthode 'run()), il est parfaitement sûr de faire' thread = new QThread (this); 'si' thread 'doit faire partie d'une autre classe. En général, évitez d'appeler 'delete' s'il existe une meilleure solution non-manuelle. Même dans le standard C++, vous avez des pointeurs intelligents et ce qui ne prend pas la charge de nettoyage manuel de vos épaules. – rbaleksandar