QThread finish()连接到QObject的删除后 [英] QThread finished() connected to deletelater of a QObject

查看:441
本文介绍了QThread finish()连接到QObject的删除后的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在问这个问题之前,我已经想了很多,读了很多文章.这些文章都没有给我适当的答案.

I have thought a lot and read lot of articles before asking this question here. None of the articles gave me a proper answer.

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();

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

Worker object has the affinity of the new thread.

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

1 > Worker finished signal will call quit() on the thread. This will end the thread's event loop and initiates the thread finished signal.

2>工作程序完成信号连接到工作程序deleteLater().根据deleteLater()文档

2 > Worker finished signal is connected to the worker deleteLater(). According to deleteLater() documentation

**计划将此对象删除. 当控制权返回事件循环时,该对象将被删除.如果事件循环>没有运行

**Schedules this object for deletion. The object will be deleted when control returns to the event loop. If the event loop is > not running

调用此函数时(例如,在 在QCoreApplication :: exec()之前的对象,该对象将被删除 一旦事件循环开始.

when this function is called (e.g. deleteLater() is called on an object before QCoreApplication::exec()), the object will be deleted once the event loop is started.

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

Note that entering and leaving a new event loop (e.g., by opening a modal dialog) will not perform the deferred deletion; for the object to be deleted, the control must return to the event loop from which deleteLater() was called.

注意:它 可以安全地多次调用此函数;当第一次推迟 传递了删除事件,该对象的所有未决事件是 从事件队列中删除.**

Note: It is safe to call this function more than once; when the first deferred deletion event is delivered, any pending events for the object are removed from the event queue.**

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

So when there is no eventloop, since the thread is already exiting and it has already raised the finished signal and we will no longer start the same thread again. In this case the deleteLater() will never be handled since the event loop doesn't exist and and worker object will not be deleted at all. Does this not create a memory leak.?

 connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
 connect(worker, SIGNAL(finished()), thread, SLOT(quit()));

如果我们认为交换两条线可以解决问题,那么我还有另一个问题. QT明确指出,发射信号时调用插槽的顺序不确定

If we think that swapping the two lines will fix the problem, then I have another question. QT clearly states that the order the slots getting called when a signal is emitted is undetermined

上面提到的文章链接中有很多评论.甚至作者也无法完全回答问题

There are bunch of comments in the article link mentioned above . Even the author was not able to answer the question completely

推荐答案

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

QThread will do a QCoreApplication::sendPostedEvents with a event type of QEvent::DeferredDelete after sending it's finished signal

换句话说,QThread将收集所有待处理的deleteLater,并在run返回后执行它们

in other words QThread will collect all pending deleteLaters and execute them after run returns

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

这篇关于QThread finish()连接到QObject的删除后的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆