3

我从多线程开始,将对象移动到 QThread 时遇到了一些麻烦。我的 Controller 类实例化 Worker,为 Worker 创建必要的线程并将 Worker 移动到新线程。当工作线程启动时,工作线程上的计算就开始了。Worker 类包含一个 Dummy 对象,在 worker 计算期间使用(函数Dummy::doDummyStuff())。一切似乎都工作正常,除了doDummyStuff()似乎是在主(控制器)线程而不是工作线程中执行的。这是因为 Worker 对象(以及因此 Dummy 对象)是首先在主线程中创建的吗?有没有办法在工作线程中移动 Worker 对象的所有类成员?

这是一个代码片段:

控制器.h

class Controller: public QObject
{
    Q_OBJECT

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

private:
    QThread workerThread_;
    Worker worker_;
    PostProcessing postProc_;

};

控制器.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();
}

工人.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_;
};

工人.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;
    }
}
4

1 回答 1

3

你的虚拟类也是从 QObject 派生的?

如果你将 dummy 设置为 worker 的子对象,那么当你调用 moveToThread 时它会自动移动。

即将worker传递给dummy的构造函数,如果它没有隐藏默认的qobject构造函数:

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

或者,您可以在工作人员和假人上调用 moveToThread 。


然而,即使没有改变任何东西,Dummy::doDummyStuff()也会在工作线程中被调用。

调用任何东西都不会改变线程,只会发出(排队)信号。

但是您不能this->thread()用来检查调用该方法的线程。它返回对象“存在”的线程,即对象的(排队的)槽将被调用的线程,如果被信号调用的话。

而是用于QThread::currentThread()查看调用方法的线程。

可以在任意线程中调用任意对象的任意方法,完全独立于对象与线程之间的关联

于 2013-10-27T18:54:54.350 回答