【问题标题】:Why does std::timed_mutex::try_lock_for not work?为什么 std::timed_mutex::try_lock_for 不起作用?
【发布时间】:2013-07-08 02:36:49
【问题描述】:

我在 Ubuntu 12.04 中使用 gcc-4.8.1(configure: ./configure --prefix=/usr/local) 编译了以下代码,但是当我运行它时,它不起作用。它并没有停下来等待互斥锁。它返回 false,并输出“Hello world!”

命令:g++ -std=c++11 main.cpp -omain -pthread

当我使用 gcc-4.6(apt-get install g++) 编译它时,它运行良好。程序等了大约十秒钟,输出“Hello world!”

#include <thread>
#include <iostream>
#include <chrono>
#include <mutex>

std::timed_mutex test_mutex;

void f()
{
    test_mutex.try_lock_for(std::chrono::seconds(10));
    std::cout << "hello world\n";
}

int main()
{
    std::lock_guard<std::timed_mutex> l(test_mutex);
    std::thread t(f);
    t.join();
      return 0;
}

【问题讨论】:

    标签: c++ c++11


    【解决方案1】:

    如果我没记错的话,就是Bug 54562 -mutex and condition variable timers。

    也提到了bug的原因:

    这是因为它使用 CLOCK_MONOTONIC 时钟(如果在 平台)来计算它需要返回的绝对时间, 这是不正确的,因为 POSIX pthread_mutex_timedlock() 调用使用 CLOCK_REALTIME 时钟,在我的平台上,单调时钟是 远远落后于实时时钟。

    但是,这并不能解释为什么您会在 gcc-4.6 上看到正确的行为。也许_GLIBCXX_USE_CLOCK_MONOTONIC 没有启用?

    【讨论】:

    • 谢谢,当我禁用 _GLIBCXX_USE_CLOCK_MONOTONIC 时,gcc-4.8 和 gcc-4.6 具有相同的行为。而且我认为他们有不同行为的原因是这个marco。
    • 对于任何想要将 gcc/g++ 升级到 4.9(已修复错误)的人,然后在 Ubuntu 上关注 these instructions,只需将 4.6 替换为 4.9。
    • 如何启用 _GLIBCXX_USE_CLOCK_MONOTONIC ?
    【解决方案2】:

    一种可能的解决方法:

    const int WAIT_PRECISION_MS = 10;  // Change it to whatever you like
    int TIME_TO_WAIT_MS = 2000;        // Change it to whatever you like
    int ms_waited = 0;
    bool got_lock = false;
    while (ms_waited < TIME_TO_WAIT_MS) {
        std::this_thread::sleep_for(
                                 std::chrono::milliseconds(WAIT_PRECISION_MS));
        ms_waited += WAIT_PRECISION_MS;
        got_lock = YOUR_MUTEX.try_lock();
        if (got_lock) {
            break;
        }
    }
    

    WAIT_PRECISION_MS 将告诉 while 循环多久“唤醒”一次并尝试获取锁。但是,它也会说明您的截止日期将有多准确,除非您的精确时间是截止时间的一个因素。

    例如:

    deadline = 20,precision = 3:3 不是 20 的因数 - while 循环的最后一次迭代将是 ms_waited 为 18 时。它表示您将总共等待 21 毫秒而不是 20 毫秒。

    deadline = 20,precision = 4:4 是 20 的因数 - while 循环的最后一次迭代将在 ms_waited 为 16 时。这意味着您将等待 20 毫秒,因为您的截止日期已定义。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-08
      • 1970-01-01
      • 2016-02-27
      • 1970-01-01
      • 2011-08-05
      相关资源
      最近更新 更多