由于英国的夏季时间,Boost计时器停止工作

时间:2011-03-28 10:31:44

标签: c++ boost timer boost-asio

我们这个周末在英国改变了时间。 从那时起,我的升压计时器已停止在我的电脑上工作。

如果我想跑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();

任何人都不知道我做错了什么,或者我是否应该做些什么来避免这个问题。

3 个答案:

答案 0 :(得分:4)

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

如果您查看asio deadline_timer(time_traits)使用的默认boost/asio/time_traits.hpp,您会看到其now()的实施使用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)

答案 1 :(得分:3)

您可以尝试使用expires_from_now,而不是手动为当前时间添加偏移量。

答案 2 :(得分:2)

我最好的选择是停止工作的原因是你使用local_time()设置一个计时器,而计时器的内部使用UTC时间,这恰好与英国的“冬天”时间相同。 Space_C0wb0y

已经给出了解决方案