完成()连接到QObject的deletelater的QThread

Sri*_*kan 7 signals quit qthread 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();
Run Code Online (Sandbox Code Playgroud)

Worker对象具有新线程的亲和力.

1> Worker完成信号将调用线程上的quit().这将结束线程的事件循环并启动线程完成信号.

2> Worker完成信号连接到worker deleteLater().根据deleteLater()文档

**安排此对象删除.当控制返回到事件循环时,将删除该对象.如果事件循环>未运行

当调用此函数时(例如,在QCoreApplication :: exec()之前在对象上调用deleteLater()),一旦启动事件循环,该对象将被删除.

注意,进入和离开新的事件循环(例如,通过打开模态对话框)将不执行延迟删除; 对于要删除的对象,控件必须返回到调用deleteLater()的事件循环.

注意:不止一次调用此函数是安全的; 在传递第一个延迟删除事件时,将从事件队列中删除该对象的任何挂起事件.**

因此,当没有eventloop时,由于线程已经退出并且它已经提升了完成的信号,我们将不再再次启动相同的线程.在这种情况下,将永远不会处理deleteLater(),因为事件循环不存在,并且根本不会删除worker对象.这不会造成内存泄漏吗?

 connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
 connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
Run Code Online (Sandbox Code Playgroud)

如果我们认为交换这两行将解决问题,那么我还有另外一个问题.QT明确指出,在发出信号时调用插槽的顺序是不确定的

上面提到的文章链接中有很多评论.即便是作者也无法完全回答这个问题

rat*_*eak 5

QThread在发送完成信号后将执行QCoreApplication::sendPostedEvents事件类型为 QEvent::DeferredDelete

换句话说,QThread将收集所有挂起的deleteLaters并在run返回后执行它们

来源: https: //qt.gitorious.org/qt/qtbase/source/c657bb7b51115d6e1719166fb502bb0ca1dcf4e8 :src/corelib/thread/qthread_win.cpp#L363-462