2013-10-27 139 views
3

我開始使用多線程,並將對象移動到QThread時遇到一些麻煩。 My Controller類實例化Worker,爲Worker創建必要的線程並將Worker移動到新線程。在工作線程啓動時,開始對工人進行計算。 Worker類包含一個Dummy對象,該對象在工人計算過程中使用(功能Dummy::doDummyStuff())。似乎一切工作正常,除了doDummyStuff()似乎在主(控制器)線程而不是工作線程執行。這是因爲Worker對象(以及Dummy對象)是在主線程中首先創建的嗎?有沒有辦法在Worker線程中移動Worker對象的所有類成員?QThread - 將類成員移至使用moveToThread的線程

這裏是一個代碼段:

或者Controller.h

class Controller: public QObject 
{ 
    Q_OBJECT 

public: 
    Controller(std::vector<double> _data, QString _fn); 
    void startControl(); 

private: 
    QThread workerThread_; 
    Worker worker_; 
    PostProcessing postProc_; 

}; 

Controller.cpp

Controller::Controller(std::vector<double> _data, QString _fn): QObject(), workerThread_(), worker_(_data), postProc_() 
{ 
    QObject::connect(&workerThread_, SIGNAL(started()), &worker_, SLOT(doWork())); 
    QObject::connect(&worker_, SIGNAL(signalResultReady(double)), &postProc_, SLOT(update(double))); 
} 

void Controller::startControl() 
{ 
    worker_.moveToThread(&workerThread_); 
    workerThread_.start(); 
} 

Worker.h

class Worker: public QObject 
{ 
    Q_OBJECT 

public: 
    Worker(std::vector<double> _coord); 

signals: 
    void signalResultReady(double); 

public slots: 
    void doWork(); 

private: 
    double res_; 
    std::vector<double> coord_; 
    Dummy dummyCreatedInWorker_; 
}; 

Worker.cpp

Worker::Worker(std::vector<double> _coord): QObject(), res_(0), coord_(_coord), dummyCreatedInWorker_() 
{ 
} 

void Worker::doWork() 
{ 
    qDebug() << "Worker thread ID" << this->thread(); 
    for(unsigned int ii = 0; ii < coord_.size(); ii++) 
    { 
     res_ += coord_[ii]; 
     dummyCreatedInWorker_.doDummyStuff(); 
     emit signalResultReady(res_); 

     /* ....*/ 
    } 
} 

假人:: doDummyStuff

void Dummy::doDummyStuff() 
{ 
    qDebug() << "Doing dummy stuff from thread" << this->thread(); 
    for(int ii = 0; ii < 10; ii++) 
    { 
     res_ += ii; 
    } 
} 
+0

是否調試在doWork()中顯示正確的線程?您可以直接從doWork()調用doDummyStuff(),因此它將在與doWork()相同的線程中執行,而與任何QObject線程親和性無關。 –

+0

是的,我在doWork()中獲得正確的線程ID。正如BeniBela指出的那樣,我在doDummyStuff()中誤用了this->線程。使用QThread :: currentThread()返回正確的線程ID。感謝您的回答! – Eph

+0

如果'this-> thread()'不等於'QThread :: currentThread()',那麼你很可能會面臨代碼中的一個錯誤,除非你明確地設計了你的'QObject'可以從多個線程訪問,並且被調用的方法具有適當的同步保護來訪問對象的數據。 –

回答

3

你的啞類也從繼承自QObject?

如果您將虛設爲工作人員的孩子,那麼當您調用moveToThread時,它將自動移動。

即通過工人到虛擬的構造函數,如果不隱藏默認的QObject的構造函數:

Worker::Worker(std::vector<double> _coord): 
    QObject(), res_(0), coord_(_coord), dummyCreatedInWorker_(this) 

或者,你可以調用moveToThread對工人虛設。


然而,即使不改變任何東西,Dummy::doDummyStuff()是所謂的工作線程。

調用任何東西都不會改變線程,只會發射(排隊)的信號。

但是,您不能使用this->thread()來檢查調用該方法的哪個線程。它返回對象「居住在」的線程,即,如果被信號調用,將調用對象的(排隊)槽的線程。

而是使用QThread::currentThread()看到線程的方法是要求收回。

可以撥打任何線程的任何對象的任何方法,它是完全獨立的對象和線程之間的關聯的

+0

事實上,使用QThread :: currentThread()會返回正確的線程ID。謝謝你的澄清 ! – Eph