std::queue::empty() not working?

std::queue::empty() not working?

本文关键字:not working queue empty std      更新时间:2023-10-16

我对这段代码简直要疯了。我有一个线程定期调用这个方法:

void deliverMsgQ() {        
    if(delMsgQ_mutex.try_lock() == false){
        return;
    }            
    while(delMsgQ.empty() == false){                
        std::vector<unsigned char> v = delMsgQ.front(); 
        delMsgQ.pop();                  
    }
    delMsgQ_mutex.unlock();
}
void processInMsgQ() {
    if(inMsgQ_mutex.try_lock()){
       if(delMsgQ_mutex.try_lock() == false){
           inMsgQ_mutex.unlock();
       } 
    }else{
        return;
    }
    while(!inMsgQ.empty()){            
        std::vector<unsigned char> msg;
        inMsgQ.front()->getData(msg); 
        std::cout << "Adding to del-msg-q: " << msg.size() << std::endl;
        delMsgQ.push(msg);
        delete inMsgQ.front();
        inMsgQ.pop();            
    }
    inMsgQ_mutex.unlock();
    delMsgQ_mutex.unlock();
}

我有另一个线程也会定期将向量推送到队列中。这两个线程是唯一接触队列delMsgQ的线程。

我的问题出现在发布的第一个函数中,出于某种原因,delMsgQ.empty()在某个时候返回false,尽管其中没有向量,因此我最终调用了pop两次。这导致大小函数变成一个巨大的不切实际的数字,然后程序进入分割故障。如果我在调用pop之前添加一个额外的检查,我可以解决这个问题,但我希望检查一次就足够了,因为我也在使用互斥锁。所以另一种选择是,也许我使用互斥锁是错误的,但据我所知,在这种情况下,这是使用互斥锁的正确方法。所以我希望也许有更聪明的人能让我知道我是否遗漏了什么?我希望这段代码就足够了,如果需要的话,我可以提供更多的代码,尽管没有其他功能接触到失败的队列。

向致以最良好的问候

processInMsgQ()中的代码(间隔稍好,但功能相同)存在问题:

if (inMsgQ_mutex.try_lock()) {
    if (delMsgQ_mutex.try_lock() == false) {
        // Point A
        inMsgQ_mutex.unlock();
        // Point B.
    }
} else {
    return;
}
// Point C.

在它锁定inMsgQ_mutex但未能锁定delMsgQ_mutex(点A)的情况下,它将释放第一个锁,然后下降到点C。这意味着你将在没有任一锁的情况下执行需要两个锁的操作,这不太可能有好的结果:-)

作为一种解决方案,可以在B点放置另一个return,但以下代码可能更干净:

// If either lock fails, return ensuring that neither is locked.
if (! inMsgQ_mutex.try_lock()) {
    return;
}
if (! delMsgQ_mutex.try_lock() {
    inMsgQ_mutex.unlock();
    return;
}
// At this point, you have both locks. Carry on ...

您会注意到,我还将您的some_boolean == false更改为更常见的! some_boolean。这是更容易接受的检查方式。