Qt:qthread在关闭期间线程仍在运行时被破坏

Posted

技术标签:

【中文标题】Qt:qthread在关闭期间线程仍在运行时被破坏【英文标题】:Qt: qthread destroyed while thread is still running during closing 【发布时间】:2015-04-24 00:19:13 【问题描述】:

我有一堂课:

class centralDataPool : public QObject

    Q_OBJECT
public:
    centralDataPool(QObject * parent = 0);
    ~centralDataPool();
    commMonitor commOverWatch;

private:
    QThread monitorThread;
    int totalNum;

signals:
    void createMonitor(int);
;

在它的构造函数中我做了:

centralDataPool::centralDataPool(QObject* parent) : QObject(parent),totalNum(0)

    connect(this, SIGNAL(createMonitor(int)), &commOverWatch, SLOT(createMonitor(int)));
    commOverWatch.moveToThread(&monitorThread);
    monitorThread.start();

当我调用此类的析构函数时,我收到错误消息:

qthread destroyed while thread is still running

但是当我试图在类centralDataPool的析构函数中终止monitorThread时,

centralDataPool::~centralDataPool()

    monitorThread.terminate();

我得到内存泄漏。

在销毁其所有者对象期间终止线程的正确方法是什么?

【问题讨论】:

你的析构代码在哪里? @ViníciusGobboA.deOliveira 查看编辑。 你不应该完成这样的线程。查看文档:doc.qt.io/qt-5/qthread.html#terminate @ViníciusGobboA.deOliveira,您好,我尝试添加 wait() 或切换到 quit(),但都不起作用...您能提供更多提示吗? 哦!我错过了。它是一个静态受保护的方法,因此如果不从QThread 继承就无法调用它。在这种情况下,您必须以某种方式向线程上正在执行的方法发出信号,表明它必须结束。无论如何,这是不泄漏的最正确方法。 【参考方案1】:

您应该注意,如果您的线程函数中有一个循环正在运行,您应该明确结束它以正确终止线程。

您可以在您的类中有一个名为finishThread 的成员变量,当应用程序将要关闭时,该变量应设置为true。只需提供一个槽,您可以在其中设置finishThread 的值。当您想要终止线程时,会发出一个信号,该信号连接到具有true 值的该插槽。 finishThread 应在循环条件中提供以在设置为true 时结束它。之后等待线程正确完成几秒钟,如果它没有完成,则强制它终止。

所以你可以在你的析构函数中有:

emit setThreadFinished(true); //Tell the thread to finish
monitorThread->quit();
if(!monitorThread->wait(3000)) //Wait until it actually has terminated (max. 3 sec)

    monitorThread->terminate(); //Thread didn't exit in time, probably deadlocked, terminate it!
    monitorThread->wait(); //We have to wait again here!

【讨论】:

我可以通过方式调用析构函数吗?删除对象; object.deleteLAter();对象->~Class();

以上是关于Qt:qthread在关闭期间线程仍在运行时被破坏的主要内容,如果未能解决你的问题,请参考以下文章

QThread:在线程仍在运行时被销毁

QThread:在线程仍在运行时被销毁

QT5线程关闭

QThreaded C++ 守护程序未正确关闭

如何在另一个 Qt 线程上运行它?

QT事件循环与QThread类的关闭quit(),wait()