我正在尝试在C++中编写一种线程池。该代码在OSX上可以正常工作,但是在Linux下,我遇到了奇怪的行为。
经过一些调试后,我发现问题是由于调用std::condition_variable::wait_until导致的,我必须以错误的方式执行此操作。

使用下面的代码,我希望循环每三秒钟循环一次:

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

using namespace std;

typedef std::chrono::steady_clock                           my_clock;
typedef std::chrono::duration<float, std::ratio<1> >        seconds_duration;
typedef std::chrono::time_point<my_clock, seconds_duration> timepoint;

timepoint my_begin = my_clock::now();

float timepointToFloat(timepoint time) {
  return time.time_since_epoch().count() - my_begin.time_since_epoch().count();
}

void printNow(std::string mess) {
  timepoint now = my_clock::now();
  cout << timepointToFloat(now) << " " << mess  << endl;;
};

void printNow(std::string mess, timepoint time ) {
  timepoint now = my_clock::now();
  cout << timepointToFloat(now) << " " << mess  << " " << timepointToFloat(time) << endl;;
};

int main() {
  mutex _global_mutex;
  condition_variable _awake_global_execution;
  auto check_predicate = [](){
    cout << "predicate called" << endl;
    return false;
  };

  while (true) {
    { // Expected to loop every three seconds
      unique_lock<mutex> lock(_global_mutex);
      timepoint planned_awake = my_clock::now() + seconds_duration(3);
      printNow("wait until", planned_awake);
      _awake_global_execution.wait_until(lock, planned_awake, check_predicate);
    }
    printNow("finish wait, looping");
  }

  return 0;
}

但是,有时我会得到如下输出:
<X> wait until <X+3>
predicate called
(...hangs here for a long time)

(其中X是一个数字),因此似乎三秒钟后未计划超时。有时我反而得到:
<X> wait until <X+3>
predicate called
predicate called
<X> finish wait, looping
<X> wait until <X+3> (another loop)
predicate called
predicate called
<X> finish wait, looping
(...continue looping without waiting)

因此似乎超时是在一小部分秒后安排的。我想我在超时时间点弄乱了东西,但是我无法弄清楚自己在做什么错。

如果可能相关,则此代码在OSX上可以正常工作,而在Linux(Ubuntu 16.04,gcc 5.4,使用“g++ main.cc -std = c++ 11 -pthread”编译)下,我遇到了奇怪的现象。

我该如何运作?

最佳答案

尝试将超时时间设置为时钟的持续时间:

auto planned_awake = my_clock::now() +
                     std::chrono::duration_cast<my_clock::duration>(secon‌​ds_duration(3));

关于c++ - C++ wait_until奇怪的超时行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47693337/

10-11 22:46
查看更多