2011-07-14 11 views
1

プロデューサ/コンシューマパターンで並行キュークラスを作成しようとしました。プロデューサ/コンシューマデザイン - Qtのスレッド間でキュー変数を共有

私は私のメインスレッドではhttp://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html

をクラスをオフに基づいて、私はそうloadTilesが私のプロデューサーである、とprocessTileは私の消費者であるQtの::並行

QFutureWatcher<void> *loadwatcher; 
loadwatcher = new QFutureWatcher<void>(); 
QString filename("myfile"); 
QFuture<void> future = QtConcurrent::run(this, &EraserBatch::loadTiles,filename); 
loadwatcher->setFuture(future); 


QFutureWatcher<bool> *procwatcher; 
procwatcher = new QFutureWatcher<bool>(); 
QFuture<bool> procfuture = QtConcurrent::run(this, &EraserBatch::processTile); 
procwatcher->setFuture(procfuture); 

を使用して、次の2つのメソッドを呼ばれます。 loadtilesで

、私はそうのようなタイルをロードしているループがあります。

for(int i =0; i < nXBlocks; i++) 
{ 
    for(int j = 0; j < nYBlocks; j++) 
    { 
     Tile *ipi = new Tile(filename); 
     sleep(1); 
     qDebug()<<"Tile pushed to queue:"<<i<<" "<<j << " Thread id:"<<this->thread(); 
     this->tiles->push(ipi); 
    } 
} 

をし、消費者の方法では、私は以下の持っている:

Tile *tile; 
this->tiles->wait_and_pop(tile); 

while(!tiles->empty()) 
{ 
      qDebug()<<"Tile popped from queue:"<<tile->tilePosX<<" "<<tile->tilePosY<< " Thread id: " << this->thread(); 
      sleep(5); 
      tiles->wait_and_pop(tile); 
    } 

これは、すべてをプッシュするようですタイルをキューに入れると、最初のタイルがポップされてキューが空になるため、消費者がwhileループに入ることはないようです。

これは設計上の瑕疵ですが、すべてのタイルがキューに追加されるまでプロデューサーに伝え、すべてのタイルが完了するまで待つように指示する方法を知っておく必要があります。私はwhileループの外側に最初のタイルをポップして、ループで使用される変数の設定情報を取得し、何度も何度も何度もやりたいと思うメモリとsuhcを割り当てる必要があります。これを設定する最良の方法は何ですか?

答えて

2

このようなシナリオでは、プロデューサは消費者にデータがもう来ないことを伝える必要があります。通常、これはキュー上にClose()メソッドを持つことで実現されます。コンシューマテストは、次のようになります。

while (!tiles->empty() || !tiles->closed()) 
{ 
    ... blocking consume 
} 
関連する問題