我们这个周末在英国改变了时间。 从那时起,我的升压计时器已停止在我的电脑上工作。
如果我想跑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();
任何人都不知道我做错了什么,或者我是否应该做些什么来避免这个问题。
答案 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
已经给出了解决方案