2013-10-27 82 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