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

Producer/Consumer design - Share queue variable across threads in Qt

本文关键字:线程 共享 变量 队列 Qt 消费者 生产者      更新时间:2023-10-16

我尝试创建一个生产者-消费者模式的并发队列类。

我基于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中,我有一个循环来加载tile,像这样:

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);
   }

这似乎将所有的tile推到队列中,然而似乎我的消费者从未进入while循环,因为我弹出第一个tile,然后队列为空。

所以这是一个设计缺陷——但我想我需要知道如何告诉制作人等待所有的贴图被添加到队列中,并一直等待直到所有的贴图都完成。我需要弹出while循环外的第一个瓷砖,以获得将在循环中使用的变量的一些设置信息,并分配一些内存等,我不想一遍又一遍地做。设置这个的最好方法是什么?

在这样的场景中,生产者需要告诉消费者不会再有数据传入。通常,这是通过在队列上使用Close()方法来实现的。你的消费者测试将变成:

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