2013-04-17 70 views
3

我遇到一个问题,QThread::currentThread()->quit();线程拒绝退出

main.cpp中:

#include <QCoreApplication> 
#include <QtCore> 
#include "myobject.h" 

QThread* cThread; 
MyObject* cObject; 

int main(int argc, char *argv[]) 
{ 
    QCoreApplication a(argc, argv); 
    cThread = new QThread(); 
    cObject = new MyObject(); 
    cObject->moveToThread(cThread); 

    QObject::connect(cThread, SIGNAL(started()), 
        cObject, SLOT(doWork())); 

    QObject::connect(cThread, SIGNAL(finished()), 
        cThread, SLOT(deleteLater())); 

    QObject::connect(cThread, SIGNAL(finished()), 
        cObject, SLOT(deleteLater())); 

    cThread->start(); 

    return a.exec(); 
} 

myobject.cpp:

#include "myobject.h" 

MyObject::MyObject(QObject *parent) : 
    QObject(parent) 
{ 
} 

void MyObject::doWork() 
{ 
    qDebug() << "Hi"; 
    QThread::currentThread()->quit(); // It is supposed to stop here, but it doesn't. 
    for (int i = 0; i < 1000000; i++) { 
     qDebug() << i; 
    } 
} 

myobject.h:

#ifndef MYOBJECT_H 
#define MYOBJECT_H 

#include <QtCore> 

class MyObject : public QObject 
{ 
    Q_OBJECT 
public: 
    explicit MyObject(QObject *parent = 0); 

signals: 

public slots: 
    void doWork(); 

}; 

#endif // MYOBJECT_H 

它应该停止在myobj ect.cpp与QThread::currentThread()->quit();但它不。

得到一个错误,说这个问题太短。

解决方法:添加“return;”退出电话后。

+0

即使事件循环正确退出,这不会阻止执行quit()调用后的for循环 –

回答

1

documentation of the function exit(这是退出话费):

注意与同名的C库函数,这 函数并返回给调用者 - 这是事件处理的是 停止

这意味着你写的代码行为,因为它应该通过进入循环。您正在停止执行线程的事件循环,这是退出所做的唯一的事情。该线程将完成doWork()的执行。

现在它引发了一个有趣的问题:将cThreadcObject删除?号码deleteLater的对象将在the control returns to the event loop时被删除。但是在这里,您刚刚停止了该线程的事件循环,因此即使发布了deleteLater,它们也不会被处理。

你的对象会存活,你会有内存泄漏。一个简单的测试将是为MyObject声明一个虚拟析构函数,它只是打印一些东西并检查它是否被调用。

+0

嗯...任何想法来解决内存泄漏?我想我将不得不返回到事件循环,然后调用quit?但问题是我没有访问事件循环。 – user2288859

+0

Qt正确处理'deleteLater()'并且不会产生内存泄漏。如果你继承了'QThread',并且用'void deleteLater()来观察它的'deleteLater()'调用qDebug()<< Q_FUNC_INFO; QThread :: deleteLater();你会在程序退出前看到它被调用。 – phyatt

0

quit函数只会终止与该线程关联的事件循环(如果有)。

默认情况下,run方法调用启动事件循环的exec方法。

眼见的QThread的代码:

emit started 
run(); 

这意味着,当开始事件发出的事件循环尚未开始,因为它只会在run方法内启动。方法退出只有在事件循环已经以exec调用启动时才会起作用。

我希望这可以帮助

+0

我没有看到他覆盖在任何地方运行... – UmNyobe

+0

是的,你是对的,我看到代码是一个不好的方法。我会解决我的答案。 –