【问题标题】:GCC 4.9.2 / GCC 4.8.1 - std::condition_variable::wait_until(...) bug?GCC 4.9.2 / GCC 4.8.1 - std::condition_variable::wait_until(...) 错误?
【发布时间】: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_timeoutstd::cv_status 的文档规定“条件变量被 notify_all、notify_one 或虚假唤醒”
  • 循环尽可能快地运行(100% cpu)。
  • 另外,这是唯一运行的线程吗?也许这是导致异常数量的虚假唤醒的根本原因。
  • 是的,它是在真实的生产代码中。上面的代码示例是如何重现该行为的示例。缺少编译器标志 -pthread。这意味着至少 c++11 线程库在某些地方开始表现得很有趣。据我了解, -pthread 标志会影响代码的编译方式。添加 -pthread 标志后,“玩具”代码和生产代码的行为都应如此。 0% cpu wile 等待时间到期。

标签: c++ c++11 gcc


【解决方案1】:

您可能需要构建具有线程支持的可执行文件。在带有 gcc 4.9.2 的 Linux 上,这将是这样的:

g++ -std=c++11 test.cpp -o test -pthread

【讨论】:

    【解决方案2】:

    好的,问题是: 我/我们使用 -lpthread 选项而不是 gcc 的 -pthread 选项。

    奇怪的是,其他东西效果很好,但这与解决方案相吻合。

    谢谢大家!

    【讨论】:

    • 接受可能有帮助的答案是正确的礼仪。 @lierdakil 的答案似乎是正确的。很高兴您的问题得到解决!
    • 对不起,这是我在这个论坛上的第一篇文章。我没有看到任何接受答案的选项..
    • 这个 Stackoverflow 链接让你知道meta.stackexchange.com/questions/5234/…
    • 谢谢!像往常一样太容易了:-)
    猜你喜欢
    • 2014-04-29
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多