我们这个周末在英国改变了时间。 从那时起,我的 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/