【问题标题】:How to implement timer callback independent of the system time in C++ using boost如何使用boost在C++中实现独立于系统时间的定时器回调
【发布时间】:2014-08-25 17:23:32
【问题描述】:

我需要创建一个计时器,它会定期(例如每 50 毫秒)调用我的函数。 但问题是我需要在计时器运行时更​​改系统时间。 我想使用 boost 来做到这一点,以便代码是可移植的。否则我在 Linux 机器上运行它。

我尝试过的事情:

  • 尝试使用 while 循环和 thread::sleep。使用 stable_clock 计算睡眠时间。
  • 也尝试使用deadline_timer

当系统时间调整后,这两个都停止工作。

问题: 有没有办法(最好使用 boost)来创建一个独立于系统时间的回调计时器? (示例代码的奖励业力)

【问题讨论】:

  • ??如果你 sleep() 间隔 50 毫秒,更改系统时间应该不会影响它。
  • 确实如此。我将系统时间向前更改(超过 50 毫秒)并且计时器停止
  • clock_gettimeCLOCK_MONOTONIC

标签: c++ linux boost timer systemtime


【解决方案1】:

似乎是linux下的一个bug。您需要使用一种睡眠方法,该方法使用CLOCK_MONOTONICboost::this_thread::sleep 使用CLOCK_REALTIME)。 boost::this_thread::sleep_for 与 boost chrono 库应该这样做,因为它使用单调时钟。

while (true) {
    // Call your function here.
    boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
}

您也可以使用boost::this_thread::sleep_until。通过该功能,您可以使用自定义时钟。

但是底层的CLOCK_MONOTONIC 可能会受到adjtime() 的影响。因此,您可以使用 CLOCK_MONOTONIC_RAW 作为 linux 唯一的替代方案。

另一种可能性:如果您能够使用 C++11,则可以使用 std::chrono::steady_clock 来获得严格的单调时钟。

auto start = std::chrono::steady_clock::now();
while (true) {
    std::cout << (start - std::chrono::steady_clock::now()).count() << std::endl;
}

如果系统时钟得到调整,这里的输出不会改变。但不要将其与boost::this_thread 一起使用。将它与std::this_thread::sleep_for 一起使用以获得正确的结果。

最后一种可能是使用usleepnanosleep

但请注意,您将无法使用最后两个选项(STL 和操作系统特定调用)中断睡眠。

【讨论】:

  • 试过了还是不行。当我向后移动系统时间时,它会停止,直到时间赶上。
  • CLOCK_MONOTONIC_RAW 可以解决这个问题,但据我所知,在 boost 中没有实现。在 STL 中有 steady_clock
  • 是的,使用 CLOCK_MONOTONIC_RAW 我让它工作但不是用 stable_clock。
  • 你有哪个系统。在带有 g++ 4.8 的 Mint 13.10 上,它适用于 steady_clock。 STL 标准规定,时钟永远不会跳动。
  • Fedora 20,boost 1.54,g++ 4.8.3
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多