c++ - 由于英国夏令时, boost 计时器停止工作

标签 c++ boost timer boost-asio

我们这个周末在英国改变了时间。 从那时起,我的 PC 上的 boost 计时器就停止工作了。

如果我想运行一个 10 秒的计时器,我应该这样做:

  boost::asio::io_service service;
  boost::asio::deadline_timer timer(service);

  boost::posix_time::ptime time = 
    boost::posix_time::microsec_clock::local_time();
  timer.expires_at(time + boost::posix_time::time_duration(0,0,10));

  timer.async_wait(boost::bind(&OnTimeOut, boost::asio::placeholders::error));
  service.run();

现在它不起作用,我没有等待,但我预计它会在 1 小时 10 秒后超时。 为了证明我的观点,如果我执行以下操作,它将在 10 秒后超时:

  boost::asio::io_service service;
  boost::asio::deadline_timer timer(service);

  boost::posix_time::ptime time = 
    boost::posix_time::microsec_clock::local_time();
  timer.expires_at(time - boost::posix_time::time_duration(0,59,50));

  timer.async_wait(boost::bind(&OnTimeOut, boost::asio::placeholders::error));
  service.run();

没有人知道我做错了什么,或者如果我应该做些什么来避免这个问题。

最佳答案

您遇到的问题是由 asio 中的默认计时器引起的,它使用 boost.date_time 的时钟,这是一个挂钟计时器。它代表您的挂钟显示的实际时间。

如果您查看 asio deadline_timer (boost/asio/time_traits.hpp) 使用的默认 time_traits,您会看到它现在实现了 () 使用 boost::posix_time::microsec_clock::universal_time()。这意味着 asio 对现在几点的理解是 UTC。当您将绝对时间传递给 expires_at() 时,asio 会将其与它理解的时间(即 UTC)进行比较。

我相信您对 local_time() 的使用只是巧合,因为它恰好与 UTC 相同。

尽管如前所述,使用没有夏令时的时钟可以显着改善这种情况,但根本问题仍然存在。

UTC 仍然不是单调时钟。它将有闰年和闰秒,但主要是用户(或更有可能是 ntpd)可以更改计算机的时钟,并且您的计时器将开始失败。

这是一个更微妙的问题,可以通过使用单调时钟定义您自己的 asio::time_traits 特化来解决。例如clock_gettime(CLOCK_MONOTONIC)

关于c++ - 由于英国夏令时, boost 计时器停止工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5457690/

相关文章:

c++ - 通过具有重载运算符函数的构造函数进行自动类型转换

C++ 堆栈和作用域

c++ - 使用 Boost 就地替换正则表达式

Java 时间延迟

ios - 如何使用打开的 ViewController 启动计时器?

javascript - 倒数计时器重置转换

c++ - 现代 C++ 游戏编程示例

c++ - 发送大量数据后,我的 send() 调用导致我的程序完全停止。这怎么可能?

c++ - 如何从字符串中转换回 Boost::thread::id?

c++ - 使用 boost asio 的 HTTPS POST 请求