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

标签 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 时,即使队列不为空,所有线程也会被终止。比如处理item失败,放回队列,此时active为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() 函数返回“正在关闭”状态而不是要处理的项目。

关于c++ - 生产者/消费者,如何确保在关闭所有消费者之前耗尽线程安全队列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37647223/

相关文章:

c# - 加入线程时是否需要内存屏障?

c++ - 返回捕获局部变量的 lambda

c++ - 访问共享内存映射文件 View 的数量 (Windows)

c++ - 我的 C++ 代码不适用于图形

multithreading - Delphi COM 对象多线程

c# - WCF 回调、代理和线程安全

java - 使用 ReentrantLock 避免死锁

C++17 <functional> 模板参数推导不适用于 Xcode 10.1

java - 具有多线程的 REST Api,用于在 Spring Boot 中处理文件

c# - C#中的有效线程同步