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

时间:2016-06-05 22:01:59

标签: c++ multithreading thread-safety pthreads producer-consumer

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

我的代码目前正在

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()的东西,并且该线程永远不会被唤醒。问题就在那里。

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

谢谢!

1 个答案:

答案 0 :(得分:1)

不要让消费者线程检查外部标志,而是让队列本身保持内部"关闭"旗。如果没有更多的工作需要处理,那么.popFront()函数将返回"关闭"状态而不是要处理的项目。