Qt:关闭期间线程仍在运行,qthread已被销毁

9

我有一个类:

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

我遇到了内存泄漏。

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


1
你的析构函数代码在哪里? - Vinícius Gobbo A. de Oliveira
@ViníciusGobboA.deOliveira 请查看修改。 - Nyaruko
1
你不应该这样结束一个线程。请查看文档:http://doc.qt.io/qt-5/qthread.html#terminate - Vinícius Gobbo A. de Oliveira
1
哦!我错过了。这是一个静态受保护的方法,因此不可能在未继承QThread的情况下调用它。在这种情况下,您必须以某种方式向正在执行线程的方法发出信号,告诉它必须结束。无论如何,这是最正确的方法,而不会泄漏。 - Vinícius Gobbo A. de Oliveira
尝试一起使用:monitorThread.quit(); monitorThread.wait(); 在析构函数中。 - Jablonski
显示剩余4条评论
1个回答

15
请注意,如果您的线程函数中有循环运行,应显式结束它以正确终止线程。
您可以在类中拥有一个名为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!
}

我可以通过哪种方式调用析构函数?delete object; object.deleteLater(); object->~Class(); - kien bui

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接