1

moveToThread メソッドのおかげで 、オブジェクトMainWorkerが別のスレッドとして実行されました。MainWorkerには、別のスレッドとしても実行されるメンバーSubWorkerがあります。両方のスレッドが無限ループで動作しています。

アイデアは、MainWorkerSubWorkerの両方がいくつかの個別の計算を実行することです。SubWorkerが計算を完了するたびに、 MainWorkerに結果を通知する必要あります。

したがって、 SubWorker によって発行されたシグナルとMainWorkerのスロットとの間の最初の接続を直感的に作成しましたが、機能していなかったため、潜在的な問題を除外するためにさらに 2 つの接続を作成しました。

connect(subWorker, &SubWorker::stuffDid, this, &MainWorker::reportStuff)); //1
connect(subWorker, &SubWorker::stuffDid, subWorker, &SubWorker::reportStuff); //2
connect(this, &MainWorker::stuffDid, this, &MainWorker::reportStuffSelf); //3

接続2と3が期待どおりに機能するため、機能していないのはまさに私が必要としているクロススレッド通信であるようです。私の質問は: 接続 1 を機能させるにはどうすればよいですか?

編集:どうやら、Karsten の説明の後、無限ループが EventLoop をブロックしていることは明らかです。新しい質問は、無限ループ スレッドからその親スレッドにメッセージ (シグナルなど) を送信するにはどうすればよいかということです。

私はQtを初めて使用します。完全に間違っている可能性が高いです。最小限の (ない) 動作例を次に示します。

MainWorker.h

class MainWorker : public QObject
{
Q_OBJECT

public:
    MainWorker() : run(false) {}

void doStuff()
{
    subWorker = new SubWorker;
    subWorkerThread = new QThread;
    subWorker->moveToThread(subWorkerThread);
    connect(subWorkerThread, &QThread::started, subWorker, &SubWorker::doStuff);
    if(!connect(subWorker, &SubWorker::stuffDid, this, &MainWorker::reportStuff)) qDebug() << "connect failed";
    connect(subWorker, &SubWorker::stuffDid, subWorker, &SubWorker::reportStuff);
    connect(this, &MainWorker::stuffDid, this, &MainWorker::reportStuffSelf);

    subWorkerThread->start();

    run = true;
    while(run)
    {
        QThread::currentThread()->msleep(200);
        emit stuffDid();
    }
}

private:
    bool run;
    QThread* subWorkerThread;
    SubWorker* subWorker;

signals:
    void stuffDid();

public slots:
    void reportStuff()
    {
        qDebug() << "MainWorker: SubWorker did stuff";
    }

    void reportStuffSelf()
    {
        qDebug() << "MainWorker: MainWorker did stuff (EventLoop is not blocked)";
    } 
};

SubWorker.h

class SubWorker : public QObject
{
    Q_OBJECT

public:
    SubWorker() : run(false) {}

    void doStuff()
    {
        run = true;
        while(run)
        {
            qDebug() << "SubWorker: Doing stuff...";
            QThread::currentThread()->msleep(1000);
            emit stuffDid();
        }
    }

private:
    bool run;

public slots:
    void reportStuff()
    {
        qDebug() << "SubWorker: SubWorker did stuff";
    }

signals:
    void stuffDid();
};

main.cpp

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    MainWorker *mainWorker = new MainWorker;
    QThread *mainWorkerThread = new QThread;
    mainWorker->moveToThread(mainWorkerThread);
    QObject::connect(mainWorkerThread, &QThread::started, mainWorker, &MainWorker::doStuff);
    mainWorkerThread->start();

    return a.exec();
}
4

0 に答える 0