C++ 条件变量 wait_for 未按预期运行

C++ condition variable wait_for not behaving as expected

我无法理解为什么我认为应该通过的测试用例大部分时间都失败了。我已将测试提炼为条件变量并使用 wait_for 方法,具体测试它是否确实至少等待指定的持续时间。

测试代码片段如下:

TEST_CASE("Condition variable test")
{
    std::mutex m;
    std::unique_lock<std::mutex> lock(m);
    std::condition_variable cv;
    bool ex = false;
    std::chrono::milliseconds rel_time(50);

    auto start = std::chrono::steady_clock::now();

    cv.wait_for(lock, rel_time, [&ex] {return(ex);});

    auto end = std::chrono::steady_clock::now();

    REQUIRE(std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() >= rel_time.count());
}

根据我对 C++11 标准的理解,我希望这应该一直通过。具有讽刺意味的是,如果我将时钟类型更改为系统时钟,我无法使测试失败。

cplusplus.com 中 condition_variable::wait_for 方法的摘录指出“如果指定了 pred (2),则该函数仅在 pred return 为假时才阻塞,并且通知只能当它变为真时解除阻塞线程(这对于检查虚假唤醒调用特别有用)。它的行为就像实现为: return wait_until (lck, chrono::steady_clock::now() + rel_time, std::move(pred ));"

这对我来说意味着使用稳定时钟获取我的参考时间戳是正确的时钟。

我正在使用带有 gcc 4.8.2 编译器的 MinGW 环境进行编译。

这听起来像是供应商实施中的错误。我不明白这个测试怎么会失败。

Fwiw,您的 REQUIRE 语句可以大大简化:

REQUIRE(end - start >= rel_time);

durations 之间的比较总是 准确。

如所写,您的测试可能会以一种方式失败:如果 std::chrono::steady_clock::duration 大于毫秒,则表达式 duration_cast<milliseconds>(end - start) 可能导致 0 毫秒。为了防止这种糟糕的实施,您可以添加:

static_assert(std::chrono::steady_clock::duration{1} <= std::chrono::milliseconds{1},
    "This steady_clock implementation has an outrageously coarse duration");