这个timer的实现是通过std::thread实现,start函数是启动一个无限循环的timer,直到调用stop结束,_try_to_expire是stop的条件,如果_try_to_expire一直为false,就每次sleep给定的时间段后执行一次task。startOnce函数是只执行一次的定时任务。
在android上用着很方便,整个定义的代码在最后,下面是程序中的一个示例。
定义一个unique_ptr 的timer:
unique_ptr<Timer> timer;然后调用start函数启动一个循环timer
if (timer == nullptr) { timer.reset(new Timer()); } timer->start(300/*300ms*/, std::bind(&Effect::doTask, this));原始代码链接:
#ifndef _TIMER_H_ #define _TIMER_H_ #include <functional> #include <chrono> #include <thread> #include <atomic> #include <memory> #include <mutex> #include <condition_variable> class Timer { public: Timer(): _expired(true), _try_to_expire(false) {} Timer(const Timer& timer) { _expired = timer._expired.load(); _try_to_expire = timer._try_to_expire.load(); } ~Timer() { stop(); } void start(int interval, std::function<void()> task) { // is started, do not start again if (_expired == false) return; // start async timer, launch thread and wait in that thread _expired = false; std::thread([this, interval, task]() { while (!_try_to_expire) { // sleep every interval and do the task again and again until times up std::this_thread::sleep_for(std::chrono::milliseconds(interval)); task(); } { // timer be stopped, update the condition variable expired and wake main thread std::lock_guard<std::mutex> locker(_mutex); _expired = true; _expired_cond.notify_one(); } }).detach(); } void startOnce(int delay, std::function<void()> task) { std::thread([delay, task]() { std::this_thread::sleep_for(std::chrono::milliseconds(delay)); task(); }).detach(); } void stop() { // do not stop again if (_expired) return; if (_try_to_expire) return; // wait until timer _try_to_expire = true; // change this bool value to make timer while loop stop { std::unique_lock<std::mutex> locker(_mutex); _expired_cond.wait(locker, [this] {return _expired == true; }); // reset the timer if (_expired == true) _try_to_expire = false; } } private: std::atomic<bool> _expired; // timer stopped status std::atomic<bool> _try_to_expire; // timer is in stop process std::mutex _mutex; std::condition_variable _expired_cond; }; #endif // !_TIMER_H_