6

我使用 gcc-4.8.1(configure: ./configure --prefix=/usr/local) 在 Ubuntu 12.04 中编译了以下代码,但是当我运行它时,它不起作用。它并没有停下来等待互斥锁。它返回 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;
}
4

2 回答 2

6

如果我没记错的话,那就是Bug 54562 -mutex 和条件变量 timers

还提到了该错误的原因:

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

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

于 2013-07-08T03:14:34.187 回答
0

一种可能的解决方法:

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 循环多久“唤醒”一次并尝试获取锁。但是,它也会告诉你的截止日期有多准确,除非你的精确时间是截止时间的一个因素。

例如:

最后期限 = 20,精度 = 3:3 不是 20 的因数 - while 循环的最后一次迭代将ms_waited是 18 的时间。这意味着您将等待总共 21 毫秒而不是 20 毫秒。

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

于 2017-11-01T11:19:00.667 回答