没有超时的C++条件变量

C++ condition variable with no time out

最近,我遇到了一个与C++中的条件变量有关的问题。代码如下所示:

#include <iostream>   
#include <thread>
#include <chrono>
#include <mutex>
#include <condition_variable>

std::condition_variable cv;
std::mutex mutex;

int main(){

std::unique_lock<std::mutex> uniqueLock(mutex);

while (true)
{

    if(cv.wait_for(uniqueLock, std::chrono::milliseconds(1000)) == std::cv_status::no_timeout)
    {
      std::cout << "has image" << std::endl;

    }
    else
    {
        std::cout<< "time out " << std::endl;
    }

}

return 0;
}

这段代码的目标是:每次在另一个线程(cv.notify())中通知条件变量时,它会在控制台中显示 "has image ",如果不能通知超过1000毫秒,显示"time out".

所以上面代码的理论输出是(因为没有通知条件变量):

time out
time out
time out
time out

但是当我在Vs2015中执行这段代码时,我发现输出很奇怪:

has image
time out
has image
time out
time out
time out
has image
has image
time out
time out
time out
time out
time out
has image
has image

我想知道为什么我有这个输出以及我怎样才能实现我的目标

谢谢!

我不知道你错误的原因是什么(但评论中有一些似是而非的解释)。但是,解决问题的一种方法是使用 wait_for 的另一个重载,其中包括谓词。

它可能看起来像这样(hasImage 在这里只是一个布尔值,将其替换为对您的需要有意义的东西 - !imageStorage.empty() 或类似的):

while (true)
{

    if (cv.wait_for(uniqueLock, std::chrono::milliseconds(1000), []() {return hasImage;}))
    {
        std::cout << "has image" << std::endl;
        hasImage = false;
    }
    else
    {
        std::cout << "time out " << std::endl;
    }

}

中肯的一点是谓词检查是否确实有新图像,如果没有则继续等待。

此方法的一个限制是,如果谓词 returns 为假(无图像),则您不知道条件变量是否由于虚假唤醒、超时或是否有实际上是一张图片,但另一个线程在这张图片醒来之前就把它拿走了。但是,如果这是您的设计可以处理的事情,那么这种变体会非常有效。