我试图以生产者 - 消费者模式创建并发队列类。
在我的主线程中,我使用Qt :: Concurrent
调用了以下两个方法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);
所以loadTiles是我的生产者,而processTile是我的消费者。
在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循环之外弹出第一个tile来获取将在循环中使用的变量的一些设置信息,并分配一些内存和suhc,我不想一遍又一遍地做。什么是最好的设置方法?
答案 0 :(得分:2)
在这样的场景中,制作人需要告诉消费者不会再有数据出现。通常,这是通过在队列上使用类似Close()
方法的方法来实现的。您的消费者测试将变为:
while (!tiles->empty() || !tiles->closed())
{
... blocking consume
}