7

スレッド化されたアプリケーションでこの各関数呼び出しを使用するのはいつですか。バッファへのデータの読み取り/書き込み(キュー操作)を処理する同じクラスで定義された2つの関数fun1()とfun2()が与えられます。これらへのマルチスレッドを実現します。2つの関数を別々のスレッドで実行する必要があります。ここで、最初に読み取られた関数がそのスレッドの開始時に呼び出されたとしましょう。

最初の関数スレッドの開始時に関数の書き込みにmoveTothread(2番目のスレッド)を使用する方が良いですか

または

新しいスレッドクラスで2番目の関数を定義し、最初のスレッドの開始時にそのスレッドを呼び出します。

4

2 に答える 2

9

Piotrが答えたように、あなたは彼が提案したリンクを実際に見る必要があります。
私はあなたの問題を理解しているので、それはあなたの問題を解決するはずです。
これは、そのブログの簡略化されたコードです。

class Producer  
{  
public:
    Producer();  

public slots:
    void produce()
    { //do whatever to retrieve the data
      //and then emit a produced signal with the data
      emit produced(data);
      //if no more data, emit a finished signal
      emit finished();
    }

signals:
    void produced(QByteArray *data);
    void finished();
};

class Consumer
{
public:
    Consumer();

public slots:
    void consume(QByteArray *data)
    {
       //process that data
       //when finished processing emit a consumed signal
       emit consumed();
       //if no data left in queue emit finished
       emit finished();
    }
};

int main(...)
{
    QCoreApplication app(...);

    Producer producer;
    Consumer consumer;

    producer.connect(&consumer, SIGNAL(consumed()), SLOT(produce()));
    consumer.connect(&producer, SIGNAL(produced(QByteArray *)), SLOT(consume(QByteArray *));

    QThread producerThread;
    QThread consumerThread;
    producer.moveToThread(&producerThread);
    consumer.moveToThread(&consumerThread);

    //when producer thread is started, start to produce
    producer.connect(&producerThread, SIGNAL(started()), SLOT(produce()));

    //when consumer and producer are finished, stop the threads
    consumerThread.connect(&consumer, SIGNAL(finished()), SLOT(quit()));
    producerThread.connect(&producer, SIGNAL(finished()), SLOT(quit()));

    producerThread.start();
    consumerThread.start();

    return app.exec();
}
于 2011-03-01T11:39:16.683 に答える
8

を使用しmoveToThreadて、オブジェクトのスレッドアフィニティを変更できます。OPが求めるのは、同じクラスの2つの関数を異なるスレッドで実行する方法です。

クラスAと2つの関数f1f2

class A
{
public:
    void f1();
    void f2(int i); 
    void run(); // shows how we can trigger f1 and f2 in different threads
}

Qtすでに異なるスレッドで関数を実行するためのクラスが提供されており、QtConcurrentRun

このQtConcurrent::run()関数は、別のスレッドで関数を実行します。関数の戻り値は、QFuture APIを介して利用可能になります。

トリガーされる関数は、外部関数またはメンバー関数のいずれかです。したがって、この場合、オブジェクト自体から開始f1f2、別のスレッドで次のことを実行したい場合は、run()

void run()
{
   // QFuture<void> because f1 is void 
   QFuture<void> future1 = QtConcurrent::run(this, &A::f1);
   int k = 5; // Concurrent run with arguments
   QFuture<void> future2 = QtConcurrent::run(this, &A::f2, k);
} 

同様に、任意のクラスの任意のパブリック関数を同時に実行できます。

QImage image = ...;
QFuture<void> future = QtConcurrent::run(image, &QImage::invertPixels, QImage::InvertRgba);

A a;
QFuture<void> future1 = QtConcurrent::run(A, &A::f1);

2つの呼び出しの違いに注意してください。

QtConcurrent::run()メンバー関数へのポインターも受け入れます。最初の引数は、const参照またはクラスのインスタンスへのポインターのいずれかである必要があります。const参照による受け渡しは、constメンバー関数を呼び出すときに役立ちます。ポインターの受け渡しは、インスタンスを変更する非constメンバー関数を呼び出す場合に役立ちます。

同時に実行される関数がいつ終了したかを確認するには、を使用する必要がありますQFutureWatcher

于 2011-11-21T10:04:31.363 に答える