【发布时间】:2015-05-09 22:15:34
【问题描述】:
我对 c++11 条件变量的方法 wait_until 有疑问。即使没有通知,该方法看起来也返回 std::cv_status::no_timeout 。下面的代码显示了问题。
下面的代码中有 cmets 说明了问题。
使用的编译器:gcc 4.9.2(在arch linux上) gcc 4.8.1(在 ubuntu 14.04 上)
我很高兴能得到任何帮助来解决这个问题。
最好的问候, 垫子
#include <iostream>
#include <atomic>
#include <condition_variable>
#include <mutex>
#include <thread>
#include <chrono>
std::mutex m;
std::condition_variable v;
void test_wait_until(int ms)
{
std::unique_lock<std::mutex> lock(m);
std::cout << ms << "ms start\n";
auto expires = std::chrono::system_clock::now() + std::chrono::milliseconds(ms);
bool run = true;
do
{
// This loop will run at 100% cpu time until
// the timeout expires.
auto status = v.wait_until(lock, expires);
if(status == std::cv_status::timeout){
std::cout << ms << "ms expired\n";
run=false;
}
if(status == std::cv_status::no_timeout){
// If the commend below is removed the
// termial will be filled by the printout.
// until the timeout expires.
//std::cout << ms << "ms did not expire\n";
}
}while(run);
}
int main()
{
test_wait_until(20000);
test_wait_until( 5000);
test_wait_until( 100);
test_wait_until( 100);
test_wait_until( 10);
test_wait_until( 0);
test_wait_until( -10);
test_wait_until( -100);
test_wait_until( -100);
test_wait_until( -5000);
test_wait_until(-20000);
}
【问题讨论】:
-
我猜这是由于虚假唤醒造成的。
no_timeout的std::cv_status的文档规定“条件变量被 notify_all、notify_one 或虚假唤醒” -
循环尽可能快地运行(100% cpu)。
-
另外,这是唯一运行的线程吗?也许这是导致异常数量的虚假唤醒的根本原因。
-
是的,它是在真实的生产代码中。上面的代码示例是如何重现该行为的示例。缺少编译器标志 -pthread。这意味着至少 c++11 线程库在某些地方开始表现得很有趣。据我了解, -pthread 标志会影响代码的编译方式。添加 -pthread 标志后,“玩具”代码和生产代码的行为都应如此。 0% cpu wile 等待时间到期。