3

私はマルチスレッドから始めていますが、オブジェクトを QThread に移動する際に問題があります。私の Controller クラスは Worker をインスタンス化し、Worker に必要なスレッドを作成し、Worker を新しいスレッドに移動します。ワーカー スレッドが開始されると、ワーカーでの計算が開始されます。Worker クラスには、ワーカーの計算中に使用される Dummy オブジェクトが含まれています (関数Dummy::doDummyStuff())。doDummyStuff()ワーカー スレッドではなくメイン (コントローラー) スレッドで実行されているように見えることを除いて、すべて正常に動作しているようです。これは、ワーカー オブジェクト (したがってダミー オブジェクト) がメイン スレッドで最初に作成されたためですか? ワーカー スレッドで Worker オブジェクトのすべてのクラス メンバーを移動する方法はありますか?

コード スニペットは次のとおりです。

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_;

};

コントローラ.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_;
};

ワーカー.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 から派生していますか?

ダミーをワーカーの子に設定すると、moveToThread を呼び出したときに自動的に移動されます。

つまり、デフォルトの 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 に答える