C++11标准stl库的timer

C/C++代码 blackfeather


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()
	{
		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); }, &param);
		Sleep(10000);
		timer3.StopTimer();
	}
}




Timer.h

#pragma once

#include <thread>
#include <functional>
#include <chrono>
#include <mutex>
#include <condition_variable>

class CTimerEvent
{
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](std::mutex *pMutex, std::condition_variable *pcondition, bool *prunning)
		{
			while (true)
			{
				//wait for timeout
				std::unique_lock<std::mutex> lock(*pMutex);
				pcondition->wait_for(lock, std::chrono::milliseconds(dwTimeout));

				if (!*prunning)
					return;

				//callback
				//printf("timer call back ... \n");
				task();
			}
		}, &m_Mutex, &m_condition, &m_bRunning);
	};


	~CTimerEvent(void)
	{
		StopTimer();
	};

	void StopTimer()
	{
		if (m_pthreadEvent)
		{
			printf("StopTimer \n");

			//stop flag
			m_bRunning = false;
			//通知一下阻塞事件
			SetTimerEvent();
			//等待线程结束
			m_pthreadEvent->join();
			delete m_pthreadEvent;
			m_pthreadEvent = NULL;
		}
	};


	//触发一次事件
	void SetTimerEvent()
	{
		std::unique_lock<std::mutex> lock(m_Mutex);
		m_condition.notify_one();
	};

private:
	std::mutex m_Mutex;
	std::condition_variable m_condition;

	std::thread *m_pthreadEvent;
	bool m_bRunning;
};


评论列表:

发表评论: