生产者/消费者设计 - 在Qt中跨线程共享队列变量

时间:2011-07-14 22:59:33

标签: c++ multithreading qt thread-safety

我试图以生产者 - 消费者模式创建并发队列类。

我将课程设为http://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html

在我的主线程中,我使用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,我不想一遍又一遍地做。什么是最好的设置方法?

1 个答案:

答案 0 :(得分:2)

在这样的场景中,制作人需要告诉消费者不会再有数据出现。通常,这是通过在队列上使用类似Close()方法的方法来实现的。您的消费者测试将变为:

while (!tiles->empty() || !tiles->closed())
{
   ... blocking consume
}