基于c++11实现的小型定时器

第一次写博客,先放代码吧...

头文件:

#ifndef __TIMERFUNC_H__
#define __TIMERFUNC_H__

#include <vector>
#include <thread>
#include <memory>
#include <functional>
#include <iostream>
#include <mutex>

class TimerElem {
public:
	TimerElem() : enabled(false) { }

	void setTimerElem(std::function<void(int index)> setFunc, int setTime) {
		time = setTime;
		func = setFunc;
		enabled = true;
	}

	void killTimerElem() {
		enabled = false;
	}

	bool enabled;
	int time;
	std::function<void(int index)> func;
};

class TimerFunc {
public:

	TimerFunc();
	~TimerFunc();

	void setTimerFunc(int &index, std::function<void(int index)> func, int outTime);
	int killTimerFunc(int &index);

private:

	void timerFuncThread();
	void addVectorElem();

private:

	std::vector<std::shared_ptr<TimerElem>> funcVector;
	int maxIndex;
	int sleepTime;
	std::shared_ptr<std::thread> timerThread;
	bool stopTimerFuncThread;
	std::mutex setMutex;
};
#endif

cpp:

#include <chrono>

#include "TimerFunc.h"

TimerFunc::TimerFunc() : maxIndex(10), stopTimerFuncThread(false), sleepTime(20)
{
	for (int i = 0; i < maxIndex; ++i) {
		auto elem = std::make_shared<TimerElem>();
		funcVector.push_back(elem);
	}

	timerThread = std::make_shared<std::thread>(&TimerFunc::timerFuncThread, this);
}

TimerFunc::~TimerFunc()
{
	stopTimerFuncThread = true;
	timerThread->join();
}

void TimerFunc::setTimerFunc(int &index, std::function<void(int index)> func, int outTime)
{
	std::unique_lock<std::mutex> lck(setMutex);
	int i = 0;
	for (i = 1; i < maxIndex; ++i) {
		if (funcVector[i]->enabled == false) {
			funcVector[i]->setTimerElem(func, outTime);
			index = i;
			return;
		}
	}

	addVectorElem();
	funcVector[i]->setTimerElem(func, outTime);
	index = i;
}

int TimerFunc::killTimerFunc(int &index)
{
	if (index <= 0 || index >= maxIndex) {
		return -1;
	}

	funcVector[index]->killTimerElem();
	index = -1;

	return 0;
}

void TimerFunc::addVectorElem()
{
	for (int i = 0; i < 5; ++i) {
		auto elem = std::make_shared<TimerElem>();
		funcVector.push_back(elem);
	}
	maxIndex += 5;
}

void TimerFunc::timerFuncThread()
{
	std::chrono::milliseconds dura(sleepTime);

	while (!stopTimerFuncThread) {
		for (int index = 1; index < maxIndex; ++index) {
			if (funcVector[index]->enabled == false)
				continue;
			funcVector[index]->time -= sleepTime;
			if (funcVector[index]->time <= 0) {
				funcVector[index]->func(index);
			}
		}

		std::this_thread::sleep_for(dura);
	}
}

测试程序:

#include "TimerFunc.h"
#include <iostream>

TimerFunc timer;

class Test {
public:
	Test() {
	}

	~Test() {
		timer.killTimerFunc(timerId); //在设置完定时器随即析构的情况下会有崩溃的风险
	}

	void testTimer() {
		auto func = std::bind(&Test::outTimerFunc, this, std::placeholders::_1);
		timer.setTimerFunc(timerId, func, 2000);
	}

	void outTimerFunc(int index) {
		std::cout << "timer id: <" << timerId << "> , index: <" << index << "> run time out func!\n";
		timer.killTimerFunc(timerId);
	}


	int timerId;
};

void testTimerTool()
{
	Test test;
	test.testTimer();

	std::cin.get();
}

int main(void)
{
	std::shared_ptr<std::thread> testThread[20];

	for (int i = 0; i < 20; ++i) {
		testThread[i] = std::make_shared<std::thread>(testTimerTool);
	}

	std::cin.get();
}

编译环境:gcc version 5.4.0 20160609

测试结果:

基于c++11实现的小型定时器

此程序精度不高,因为在项目中对时间的精确度要求不高,所以也可以这样用。

另外有一个致命的缺点是在回调中运行耗时操作会耗费整个定时器的时间,现在没有什么很好的办法来解决此问题。

希望各位大佬来提意见改进这个小小的定时器!在此拜谢...