2013-04-17 78 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

是的,你是對的,我看到代碼是一個不好的方法。我會解決我的答案。 –