基于boost asio实现的定时器
基于boost asio实现的定时器,包括一次性定时器、循环定时器、带开始时间的循环定时器
#pragma once
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/date_time.hpp>
#include <iostream>using TimerCallbackFuncT = std::function<void()>;template <bool Periodic>
class Timer
{
public:Timer(boost::asio::io_context& io, int interval, TimerCallbackFuncT callback): m_interval(interval), m_timer(io, m_interval), m_callback(callback), m_periodic(Periodic){}~Timer() { m_timer.cancel(); }void Start() { m_running = true; AsyncWait(); }void Stop(){m_running = false;m_timer.cancel();}void Reset(int interval){boost::posix_time::seconds intv(interval);m_timer.expires_from_now(intv);}std::string ExpiresAt(){auto dt = m_timer.expires_at();boost::local_time::time_zone_ptr zone(new boost::local_time::posix_time_zone("EST+08:00:00"));boost::local_time::local_date_time dt_with_zone(dt, zone);std::stringstream strm;strm.imbue(std::locale(std::cout.getloc(), new boost::local_time::local_time_facet("%Y-%m-%d %H:%M:%S UTC%Q")));strm << dt_with_zone;// std::cout << "timer: " << strm.str() << std::endl;return strm.str();}private:void AsyncWait() { m_timer.async_wait(boost::bind(&Timer::Hook, this, boost::asio::placeholders::error)); }void Hook(const boost::system::error_code& ec){if (ec){std::cout << "Timer error_code:(" << ec.value() << ") " << ec.message() << std::endl;}else if (m_callback){m_callback();}if (m_periodic && m_running){m_timer.expires_from_now(m_interval);// m_timer.expires_at(m_timer.expires_at() + m_interval);AsyncWait();}}private:// boost::asio::io_context& m_io_context;boost::posix_time::seconds m_interval;boost::asio::deadline_timer m_timer;TimerCallbackFuncT m_callback;bool m_periodic;std::atomic<bool> m_running{false};
};using PeriodicTimer = Timer<true>;
using OnceTimer = Timer<false>;class PeriodicWithStartTimer
{
public:PeriodicWithStartTimer(boost::asio::io_context& io, int interval, int start, TimerCallbackFuncT callback): m_ptimer(io, interval, callback), m_otimer(io, start, std::bind(&PeriodicWithStartTimer::OnStart, this)), m_interval(interval){}void Start() { m_otimer.Start(); }void Stop(){m_otimer.Stop();m_ptimer.Stop();}std::string ExpiresAt(){std::stringstream ss;ss << "[" << m_otimer.ExpiresAt() << "][" << m_ptimer.ExpiresAt() << "]";return ss.str();}private:void OnStart(){m_ptimer.Reset(m_interval);m_ptimer.Start();}PeriodicTimer m_ptimer;OnceTimer m_otimer;int m_interval;
};