生产者/消费者设计 - 在 Qt 中跨线程共享队列变量
我尝试以生产者-消费者模式创建一个并发队列类。
在我的主线程中,我使用 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 循环之外弹出第一个图块,以获取将在循环中使用的变量的一些设置信息,并分配一些内存和 suhc,我不想一遍又一遍地这样做。设置此功能的最佳方法是什么?
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 then 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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在这种情况下,生产者需要告诉消费者不会再有数据了。通常,这是通过在队列上使用类似
Close()
方法来实现的。您的消费者测试将变成: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: