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");
我无法理解为什么我认为应该通过的测试用例大部分时间都失败了。我已将测试提炼为条件变量并使用 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");