生产者/使用者,如何确保在关闭所有使用者之前耗尽线程安全队列

Producer/Consumer, How to make sure a thread safe queue is drained before turning off all consumers?

本文关键字:使用者 队列 安全 线程 何确保 生产者 确保      更新时间:2023-10-16

我正在使用线程安全队列处理一个项目。这基本上是一个生产者/消费者的问题。

我目前的代码是

void threadCode()//the consumer
{
    while(active) // active is an atomic int, we use it to turn off everything during destruction
    {
        threadSafeQueue.popFront();//if queue is empty, it will wait for a signal.The queue has a CV.
        // process it
        // if it fails to process it but less than three times, 
        // put it back to the queue to retry later
    }
}

问题是,当我的析构函数将 active 更改为 0 时,即使队列不为空,所有线程都将终止。例如,它无法处理项目,将其放回队列,然后活动现在为 0。

我不希望这种情况发生。我希望在处理队列中的所有内容后销毁实例。

所以我试了这个,

void threadCode()
{
    while( active || queue.size() != 0 )
    { //[1]
        queue.popFront();
        //process
        // put it back to the queue if it fails less than 3 times
    }
}

queue.size() 和 queue.popFront() 是线程安全的。但将它们放在一起并不是...如果队列中只剩下一件事,并且上下文切换发生在 [1]。该线程可能会永远沉睡。

因为我在析构函数中有类似 threadpool.join() 的东西,并且该线程永远不会唤醒。问题就卡在那里了。

我想知道有没有人有更好的主意来解决这个问题?

谢谢!!

不要让使用者线程检查外部标志,而是让队列本身维护一个内部"关闭"标志。 如果没有更多要处理的工作,则 .popFront() 函数返回"正在关闭"状态,而不是要处理的项目。