C ++条件变量wait_for的行为不符合预期

时间:2015-06-03 18:21:31

标签: c++ c++11 condition-variable chrono

我有一个问题,理解为什么我认为应该通过的测试用例在大多数情况下失败。我已经将测试提炼到条件变量并使用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标准的理解,它应该始终通过。具有讽刺意味的是,如果我将时钟类型更改为系统时钟,我就无法使测试失败。

条件变量:: wait_for方法的cplusplus.com摘录说明&#34;如果指定了pred(2),则该函数仅在pred返回false时才会阻塞,并且通知只能解除阻塞变为真(这对于检查虚假的唤醒呼叫特别有用)。它表现得好像实现为: return wait_until(lck, chrono :: steady_clock :: now() + rel_time,std :: move(pred));&#34;

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

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

1 个答案:

答案 0 :(得分:3)

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

Fwiw,您的REQUIRE声明可以大大简化:

REQUIRE(end - start >= rel_time);

durations之间的比较总是完全正确。

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

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