timer定时器,多线程,回调为阻塞模式。支持参数绑定,非常好使。
用法:
////////////////////////////////////////////////////////////////////////// //以下是测试代码 namespace timertester { class timertestclass { public: timertestclass(){}; ~timertestclass(){}; void testfn() { CTimerEvent mTimer(3000, &timertestclass::threadfn, this); for (int i = 0; i < 5; i++) { getchar(); mTimer.SetTimerEvent(); } printf("stop timer \n"); mTimer.StopTimer(); }; void threadf(int i) { printf("test f i:%d\n", i); }; void threadfn() { printf("test fn d\n"); }; void threadfn2() { printf("test fn2222 \n"); }; }; static void testfn1(timertestclass *cls) { cls->threadfn(); } static void testpf() { printf("test printf \n"); printf("callback ret. \n"); } static void timertest() { //如果定时为0,则每次为手动触发 CTimerEvent timerman(0, [](){ printf("timerman in.\n"); Sleep(5000); printf("timerman out.\n"); }); timerman.SetTimerEvent(); timerman.SetTimerEvent(); timerman.StopTimer(); timertestclass test1; test1.testfn(); int x = 0; CTimerEvent timerref(1000, [&x]() { printf("x: %d \n", x); }); for (int i = 0; i < 10; i++) { x = i; Sleep(1000); } timerref.StopTimer(); CTimerEvent timerx(1000, [&test1]() { test1.threadfn2(); }); Sleep(10000); timerx.StopTimer(); CTimerEvent timer0(1000, testpf); Sleep(10000); timer0.StopTimer(); CTimerEvent timer1(1000, testfn1, &test1); Sleep(10000); timer1.StopTimer(); CTimerEvent timer2(1000, [](){ printf("lambada no param \n"); }); Sleep(10000); timer2.StopTimer(); int param = 0; CTimerEvent timer3(1000, [](int *p){ printf("lambada with param: %d \n", *p); }, ¶m); Sleep(10000); timer3.StopTimer(); } }
Timer.h
#pragma once #include <thread> #include <functional> #include <chrono> #include <mutex> #include <atomic> #include <condition_variable> class CTimerEvent { private: std::mutex m_Mutex; std::condition_variable m_Condition; std::thread *m_pthreadEvent; bool m_bRunning; std::thread::id m_threadEventID; public: template <class callable, class... arguments> CTimerEvent(uint32_t dwTimeout, callable&& f, arguments&&... args) { m_bRunning = true; std::function<typename std::result_of<callable(arguments...)>::type()> task(std::bind(std::forward<callable>(f), std::forward<arguments>(args)...)); m_pthreadEvent = new std::thread([dwTimeout, task, this]() { while (true) { //wait for timeout std::unique_lock<std::mutex> lock(this->m_Mutex); bool waitret = false; if (dwTimeout) this->m_Condition.wait_for(lock, std::chrono::milliseconds(dwTimeout)); else this->m_Condition.wait(lock); if (!this->m_bRunning) return; //callback //printf("timer call back ... \n"); task(); } printf("timer thread exit.\n"); }); }; ~CTimerEvent(void) { StopTimer(); }; void StopTimer() { if (m_pthreadEvent) { printf("Stop Timer \n"); //stop flag m_bRunning = false; //通知一下阻塞事件 SetTimerEvent(); //等待线程结束 m_pthreadEvent->join(); m_pthreadEvent = NULL; printf("Timer has Stopped. \n"); } }; //触发一次事件 如果正在执行回调任务,此函数会阻塞,回调函数返回后此函数才会进去 void SetTimerEvent() { //不允许在回调方法里面去Stop和Set事件 if (std::this_thread::get_id() != m_pthreadEvent->get_id()) { std::unique_lock<std::mutex> lock(this->m_Mutex); m_Condition.notify_one(); } }; };