Queue.empty() 为假,但队列大小为 0

Queue.empty() is false, but the queue size is 0

我有一个 std::queue<std::vector<char>> GLOB_DATA_QUEUE; 用于将数据从一个线程传输到另一个线程。尝试从队列中读取时遇到一个奇怪的错误。这是我阅读的代码(已更新为完全独立的):

#include <vector>
#include <queue>
#include <iostream>


// global data pipe object instaciation
// queue for data
std::queue<std::vector<char>> GLOB_DATA_QUEUE;
// global mutex for the thread
std::mutex GLOB_MUTEX;
// global condition variable for producer/consumer
std::condition_variable GLOB_CV;


int main(int argc, char *argv[])
{
      // flow control for main logic loop
    bool keep_running = true;
    
    // this is the main loop we never plan to exit until shutdown
    while(keep_running)
    {
        
        std::cout<<"servicing data queue"<<std::endl;
        // sensor thread gets prioity, so if we can't have the mutex right now, go do something else
        if(GLOB_MUTEX.try_lock())
        {
            std::cout<<"servicing data queue: got lock"<<std::endl;
            std::cout<<"queue size: "<< GLOB_DATA_QUEUE.size() << std::endl;
            
            if(!GLOB_DATA_QUEUE.empty()); // TODO - copy to local variable and release mutex before anything else
            {
                std::cout<<"servicing data queue: pop with queue size: " << GLOB_DATA_QUEUE.size() <<std::endl;
                GLOB_DATA_QUEUE.pop();
            }
            std::cout<<"servicing data queue: unlocking"<<std::endl;
            GLOB_MUTEX.unlock();
                
            // TODO: do something with the data
        }
            
        std::cout<<"finished servicing data queue"<<std::endl;
    
    }
        
        
}

在测试期间,我 运行 在没有提供程序线程的情况下定期执行上述操作 运行 (因此没有任何内容被输入到队列中)。似乎发生的是 .empty() 不断返回 false,即使队列为空。这是我得到的输出:

servicing data queue
servicing data queue: got lock
queue size: 0
servicing data queue: pop with queue size: 0
servicing data queue: unlocking
finished servicing data queue
servicing data queue
servicing data queue: got lock
queue size: 4294967295
servicing data queue: pop with queue size: 4294967295
servicing data queue: unlocking
finished servicing data queue

重复几次后出现段错误。显然,问题是在空队列上调用 .pop(),但我不明白为什么会这样,以及如何解决它。此时甚至 运行 都没有其他线程,所以没有其他线程接触队列,而且互斥锁在两端都已就位。任何想法或指示将不胜感激。

我的猜测是问题不在您向我们展示的代码中,而是在您代码的其他部分中 - 虽然很难说,因为您没有包含它。

您的第三个输出行“queue size: 0”来自您代码的另一部分。所以我认为发生的是,在空检查行之后,另一个线程运行并清空队列而不使用互斥锁。 因此,当这个线程到达下一行时,队列突然变空了,因为另一个线程在这些行之间清空了它。

让一部分代码受互斥锁保护没有任何帮助,除非修改同一变量的所有代码都受同一互斥锁保护。

所以去检查你的其他代码,看看输出“queue size: 0”的地方,你可能会找到原因。

作为@G.M。在上面的评论中指出,替换

if(!GLOB_DATA_QUEUE.empty());

if(!GLOB_DATA_QUEUE.empty())

此外,add -Wall to your compiler flags,如果您说“请告诉我我是否做错了什么,请告诉我”,这是编译器可以捕捉到的东西。