如果 QThread 的完成信号连接到 deleteLater,是不是有必要删除在 QThread 上运行的对象?

Posted

技术标签:

【中文标题】如果 QThread 的完成信号连接到 deleteLater,是不是有必要删除在 QThread 上运行的对象?【英文标题】:Is it necessary to delete an object if that runs on a QThread if finished signal of QThread is connected to deleteLater?如果 QThread 的完成信号连接到 deleteLater,是否有必要删除在 QThread 上运行的对象? 【发布时间】:2019-07-17 21:59:34 【问题描述】:

所以我在构造函数中有以下代码。

m_someObject = new SomeObject();
m_someObject->moveToThread(&m_thread);
m_thread.start();

connect(&m_thread, &QThread::finished, m_someObject, &QObject::deleteLater);

我在析构函数中有以下代码。

 m_thread.terminate();
 while (m_thread.isRunning())
 
 

尽管已经完成了连接到m_someObjectdeleteLater 插槽的m_thread,我是否还需要删除m_someObject

【问题讨论】:

是什么让您认为m_someObject 不会被删除?这对我来说看起来不错。 因为m_someObject 的析构函数永远不会被调用。 @RickPat 也许尝试用m_thread.wait()替换while (m_thread.isRunning()) m_thread.terminate(); 杀死线程。你不应该调用它。文档说明了这一点:警告:此功能很危险,不鼓励使用。线程可以在其代码路径中的任何位置终止。修改数据时可以终止线程。线程没有机会自行清理、解锁任何持有的互斥锁等。简而言之,只有在绝对必要时才使用此功能。 true,将代码替换为m_thread.quit(); m_thread.wait(); 【参考方案1】:

不,没有必要。只要线程最终发出完成,连接就应该完全按照您的要求进行。请参阅以下代码:

#include <QObject>
#include <QThread>
#include <iostream>

class Test : public QObject 
    Q_OBJECT
public:
    Test()
        std::cout <<"c'tor" << std::endl;
    
    ~Test()
        std::cout << "d'tor" << std::endl;
    
;

void startThread()
    QThread* thr = new QThread();
    Test* test = new Test();
    connect(thr, &QThread::finished, test, &QObject::deleteLater);
    test->moveToThread( thr );
    thr->start();
    thr->quit();
    thr->wait();
    delete thr;

输出如预期:

c'tor
d'tor

请注意,sn-p 不会立即编译,因为它缺少一个 main。

【讨论】:

以上是关于如果 QThread 的完成信号连接到 deleteLater,是不是有必要删除在 QThread 上运行的对象?的主要内容,如果未能解决你的问题,请参考以下文章

QThread 的started() 信号没有发出

Qt信号发射和QThread执行流程

使用 PySide2 将 python 信号连接到 QML ui 插槽

QThread 线程间通信:连接到 &QThread::quit 与连接到 lambda [&thread] thread->quit(); 的奇怪行为

驻留在 QThread 内的 QObjects 会自动删除吗?

在 QThread::run 中间调用了一个插槽