4

スレッドで実行する必要があり、スロットのイベント ループが必要なクラスがあります。現在は でうまく実行していますがmoveToThread()、使用したいのですQThreadPoolが、問題が発生しました。

QThreadPool私のランナブルのrun()メソッドで実行すると、プールされたスレッドから呼び出されます(これを で確認しますQThread::currentThread())が、プールされたスレッドでスロットが実行されていないため、オブジェクトがプール内のスレッドに移動されていないと思います。

これは、スロットがレシーバーのスレッドで実行されていることを知っているためだと思います。これは、moveToThread()メソッドとQThread.

QRunnableプールされたスレッドで完全に実行されるようにするにはどうすればよいですか? それとも、私が間違っているか、間違っていると理解していますか?

次の POC は、問題を示しています。

foo.h

#ifndef FOO_H
#define FOO_H

#include <QObject>
#include <QRunnable>
#include <QEventLoop>

class Foo : public QObject, public QRunnable
{
    Q_OBJECT
public:
    explicit Foo(int data, QObject *parent = 0);
    void run();
signals:
    void startWorking();
public slots:
    void doWork();

private:
    QEventLoop eventLoop;
    int data;
};

#endif // FOO_H

foo.cpp

#include "foo.h"

#include <QThread>
#include <QDebug>

Foo::Foo(int d, QObject *parent) :
    QObject(parent), eventLoop(this), data(d)
{
}

void Foo::run()
{
    qDebug() << "run() in: " << QThread::currentThread();
    connect(this, SIGNAL(startWorking()), this, SLOT(doWork()));
    emit startWorking();
    eventLoop.exec();
}

void Foo::doWork()
{
    qDebug() << "doWork() in: " << QThread::currentThread();
}

main.cpp

#include <QCoreApplication>
#include <QThreadPool>

#include "foo.h"

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

    Foo *foo = new Foo(42);

    QThreadPool::globalInstance()->start(foo);

    return a.exec();
}

ただし、実際のコードでは、ネットワーク上でデータを受信した後であるため、信号はすぐには送信されないことに注意してください。

PS: POC はこちらからもご覧いただけます

4

3 に答える 3

2

ロジックclass Fooを 2 つに分割することもできます。とワーカーを使用
するホストQRunnableで、メソッドを呼び出す前にワーカー スレッドで作成します。次に、すべてのシグナルをワーカー オブジェクトに転送します。これで、プールされたスレッドでスロットが呼び出されます。 ただし、同時に多数のスレッドを作成することなく、多数の短いタスクを実行するように設計されています。一部のタスクはキューに入れられ、他のタスクが完了するのを待っています。これが意図しない場合は、古き良きものに戻って代わりに使用することをお勧めします。QEventLoopQObjectrun()QEventLoop::exec
QThreadPoolQThread

于 2013-07-26T08:31:40.107 に答える