2011-03-01 6 views
6

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

それは新しい における第2の機能を定義する第一 機能スレッド

または

の開始時 機能ライトためmoveTothread(第2スレッド)を使用する方がよいですそのスレッドを に呼び出すと、最初のスレッドの開始点になります。

+0

関連:[QThreadブロッキングメインアプリケーション](http://stackoverflow.com/questions/3213738/) –

答えて

8


これは、ブログから単純化されたコードです。 OPが尋ねることは、同じクラスの2つの関数を異なるスレッドで実行する方法です。

レッツクラスAとの二つの機能f1f2

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

Qtは、すでに別のスレッドで関数を実行するためのクラスを提供し、QtConcurrent::run()関数は関数を実行しますQtConcurrentRun

と呼ばれています別スレッド この関数の戻り値は、QFuture APIから利用できます。

トリガーされる機能は、外部機能またはメンバー機能のいずれかになります。我々は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); 
} 

で次の操作を行うことができ、異なるスレッドでf1f2を開始するには、オブジェクト自体から望んでいたのであれば我々の場合においても同様に、あなたは、同時に例えば

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

A a; 
QFuture<void> future1 = QtConcurrent::run(A, &A::f1); 
を任意のクラスの任意のパブリック関数を実行することができます

お知らせの二つの呼び出しの違いは:

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

同時に実行された機能が終了したときを確認するには、QFutureWatcherを使用する必要があります。

9

Piotrは、彼が提案したリンクを実際に見てみるように答えました。
私はあなたの問題を理解するので、それはあなたの問題を解決するはずです。我々は、オブジェクトのスレッド親和性を変更することができますmoveToThreadを使用

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(); 
} 
+0

これは私が解決しようとしていた問題の完全なリファレンスでした。良い慣用的なQtアプローチです。私は、 'consum()'シグナルを 'produce()'スロットから切り離し、プロデューサの 'finished()'シグナルを消費者の 'finished()'シグナルと接続するだけでした。このようにして、プロデューサは消費者を待たずに、消費者にそれが終了するのが安全であることを通知します。 – russdot

関連する問題