事实上,boost::asio::steady_timer就是一个这样的定时器,它基于std::chrono::steady_clock实现。std::chrono::steady_clock是一个稳定的时钟,不随系统时间变化而变化。既然如此,直接用steady_timer代替deadline_timer不就可以了吗?理论上来说是可以的,但实际上,在Visual C++ 2013环境下,这是行不通的,因为Visual C++ 2013标准库中的std::chronno::steady_clock并不符合标准,它仍然会受系统时间影响!
有三种方法可以解决这个问题。第一是升级到Visual C++ 2015,这个版本的std::chronno::steady_clock总算符合标准了;第二是修改boost的编译选项,定义BOOST_ASIO_DISABLE_STD_CHRONO宏,这样可以禁止boost使用std::chrono,转而使用boost::chrono;第三是本文要介绍的方法,即定制deadline_timer,让它变成稳定的定时器。
/// Time traits specialised for posix_time. template <> structtime_traits<boost::posix_time::ptime> { /// The time type. typedef boost::posix_time::ptime time_type;
/// The duration type. typedef boost::posix_time::time_duration duration_type;
/// Get the current time. static time_type now() { #if defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK) return boost::posix_time::microsec_clock::universal_time(); #else// defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK) return boost::posix_time::second_clock::universal_time(); #endif// defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK) }
/// Add a duration to a time. static time_type add(const time_type& t, const duration_type& d) { return t + d; }
/// Subtract one time from another. static duration_type subtract(const time_type& t1, const time_type& t2) { return t1 - t2; }
/// Test whether one time is less than another. staticboolless_than(const time_type& t1, const time_type& t2) { return t1 < t2; }