gpt4 book ai didi

c++ - Qt:这是生产者-消费者模式中消费者退出的正确方式吗?

转载 作者:搜寻专家 更新时间:2023-10-31 01:40:30 24 4
gpt4 key购买 nike

制作人:

// it is in the GUI thread
...

MtileLoadQueue.lock();
{
if(!tileLoadQueue.contains(task))
{
MtileToload.lock();
++tilesToload;
MtileToload.unlock();
tileLoadQueue.enqueue(task);
loaderLimit.release();//loaderLimit is a semaphore
}
}
MtileLoadQueue.unlock();

消费者将其子类化为 QThread:

consumer::run(){
while (!finish)
{
loaderLimit.acquire();//loaderLimit is a semaphore

LoadTask task;

MtileLoadQueue.lock();
{
if (tileLoadQueue.count() > 0)
{
task = tileLoadQueue.dequeue();
}
}
MtileLoadQueue.unlock();
//deal with the task...
Mfinish.lock();
finish = quit; //quit is initialized as false
Mfinish.unlock();
}
}

当我希望消费者 QThread 完成其任务(以允许运行函数返回)时,我这样做了(从 GUI 线程):

    Mquit.lock();
quit = true;
Mquit.unlock();
loaderLimit.release();
wait();

然后 run() 函数可以返回并且消费者线程完成它的工作。

这个方法的正确性如何?关于如何退出消费者线程,有没有更好的解决方案,因为我担心退出时是否有可能出现死锁。

最佳答案

根据队列元素的类型,可以有多种解决方案。

  • 如果元素是指针—— nullptr永远不可能是一个有效的对象,那么也许生产者可以添加 nullptr (通常称为 poision 对象)到队列中,以通知消费者退出。注意,如果有很多消费者,那么每个消费者都要加上nullptr退出前再次加入队列,以便通知其他消费者。

  • 如果元素是多态对象(指针1 或引用),那么生产者可以使用 poison_task 的对象通知消费者。

  • 如果元素既不是指针也不是多态引用,那么:

    • 生产者可以使用标记值来通知。
    • 元素类型可以是boost::optional<T>其中一个空的可选值可以用作毒物对象。
    • 元素类型可以是std::pair<bool,T> .first在哪里说是否.second是一个有效的对象,或者是一种毒药。请注意,在这种情况下,T必须是默认可构造的。

使用适合您的情况。

1.请注意,在这种情况下,您可以使用 nullptr ,因为对象是指针。

关于c++ - Qt:这是生产者-消费者模式中消费者退出的正确方式吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29719260/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com