开发者

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

I have tried to create a concurrent queue class, in a producer-consumer pattern.

I based the class off http://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html

In my main thread, I called the following two methods using 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);

so loadTiles is my producer, and processTile is my consumer.

in loadtiles, I have a loop that is loading the tiles like so:

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

and in the consumer method, i have the following:

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

This seems to push all of the tiles to the queue, however it seems like my consumer never makes it into the while loop, because i pop the first tile, and th开发者_如何转开发en the queue is empty.

So this is a design flaw - but I guess I need to know how to tell the producer to wait for all tiles to be added to the queue, and keep waiting until all of them are done. I need to pop the first tile outside the while loop to get some setup info for variables that will be used in the loop, and to allocate some memory and suhc, that i dont want to do over and over. Whats the best way to set this up?


In a scenario like this the producer needs to tell the consumer that no more data will be coming. Typically this is achieved by having something like a Close() method on the queue. Your consumer test would then become:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜