最近在工做上須要用到定時器,而後看到boost裏面的deadline_timer能夠實現一個定時器,因此就直接將其封裝成了ATimer類,方便使用,ATimer有如下優勢:ios
ATimer和Qt的QTimer使用方法相似,若沒有相似的Timer類,使用最原始的方法,咱們的代碼可能會是這樣的:git
m_timerThread = std::thread([this] { while (!m_bThreadStoped) { ++m_sleepCount; Sleep(SLEEP_DURATION_TIME); if (m_sleepCount == m_sleepAllCount) { m_sleepCount = 0; doSomeThing(); } } });
若使用QTimer的話,書寫是這樣的:github
QTimer *timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(update())); timer->start(1000);
再來看看ATimer的使用:async
ATimer<> t; t.bind([]{ std::cout << "Hello C++" << std::endl; }); t.start(1000);
從上面的例子能夠看到,QTimer和ATimer的使用都很是方便,接下來看看ATimer的具體實現:this
// ATimer.hpp #ifndef _ATIMER_H #define _ATIMER_H #include <vector> #include <thread> #include <atomic> #include <functional> #include <boost/timer.hpp> #include <boost/asio.hpp> template<typename Duration = boost::posix_time::milliseconds> class ATimer { public: ATimer() : m_timer(m_ios, Duration(0)), m_isSingleShot(false) {} ~ATimer() { stop(); } void start(unsigned int duration) { if (m_ios.stopped()) { return; } m_isActive = true; m_duration = duration; m_timer.expires_at(m_timer.expires_at() + Duration(m_duration)); m_func = [this] { m_timer.async_wait([this](const boost::system::error_code&) { for (auto& func : m_funcVec) { func(); } if (!m_isSingleShot) { m_timer.expires_at(m_timer.expires_at() + Duration(m_duration)); m_func(); } }); }; m_func(); m_thread = std::thread([this]{ m_ios.run(); }); } void stop() { m_ios.stop(); if (m_thread.joinable()) { m_thread.join(); } m_isActive = false; } void bind(const std::function<void()>& func) { m_funcVec.emplace_back(func); } void setSingleShot(bool isSingleShot) { m_isSingleShot = isSingleShot; } bool isSingleShot() const { return m_isSingleShot; } bool isActive() const { return m_isActive; } private: boost::asio::io_service m_ios; boost::asio::deadline_timer m_timer; std::function<void()> m_func = nullptr; std::vector<std::function<void()>> m_funcVec; std::thread m_thread; unsigned int m_duration = 0; std::atomic<bool> m_isSingleShot; bool m_isActive = false; }; #endif
下面是ATimer的具體使用例子:atom
// main.cpp #include <iostream> #include "ATimer.hpp" void test() { std::cout << "Timer thread id: " << std::this_thread::get_id() << std::endl; } int main() { std::cout << "Main thread id: " << std::this_thread::get_id() << std::endl; ATimer<boost::posix_time::minutes> t0; t0.setSingleShot(true);// 單次調用 t0.bind(test); t0.start(1);// 一分鐘以後調用 ATimer<> t;//默認使用毫秒定時器 t.bind(test); t.bind([]{ std::cout << "Hello C++" << std::endl; }); t.start(1000);//每1000ms調用一次 std::cin.get(); t0.stop(); t.stop(); std::cout << "Tiemr stop" << std::endl; std::cin.get(); std::cout << "Process end" << std::endl; return 0; }
該例子的github地址:https://github.com/chxuan/samples/tree/master/ATimercode