c++ 时间轮与时间堆定时器

相应的参考链接与注释都在代码里面,不懂的可以直接点开链接查看。
注释:时间轮定时器是指定时间间隔和一轮的总时间进行定时,时间堆定时器是指定执行次数和时间间隔进行定时(不要删除定时器)。

时间轮定时器

TimeWheel.h

#pragma once

#ifndef __TIMEWHEEL_H__
#define __TIMEWHEEL_H__
/*
参考链接
https://cloud.tencent.com/developer/article/1361827
https://www.cnblogs.com/zhongwencool/p/timing_wheel.html
*/

/************************************************************************/
/* TimeWheel实现了一个毫秒级别的定时器,最大支持到分钟级别 
进行了修改了,定时器函数,支持接收任意参数,返回类型为void
/************************************************************************/
#include <functional>
#include <list>
#include <thread>
#include <mutex>


typedef struct TimePos_
{
	//毫秒,秒,分钟
	int ms_pos;
	int s_pos;
	int min_pos;

}TimePos;

typedef struct EventInfo_
{
	//超时时间(为初始化的倍数)
	int interval;
	//回调函数
	std::function<void()>  call_back;
	//时间
	TimePos time_pos;
	//定时器ID
	int timer_id;

}EventInfo;

class TimeWheel
{
public:
	TimeWheel();
	~TimeWheel();
public:
	/*
	step 以毫秒为单位,表示定时器最小时间粒度
	max_timer 表示定时器所能接受的分钟时间间隔,表示一轮时间的总分钟数
	*/
	int InitTimerWheel(int step,int max_min);
	//设置时间为TimeOut的事件时,根据TimeOut算出发生此事件时刻的指针位置{TriggerMin,TriggerS,TriggerMS};
	template<typename Func, typename... Args>
	int AddTimer(int interval, Func&& func, Args&& ... args);
	int DeleteTimer(int timer_id);

private:
	int DoLoop();
	int GenerateTimerID();
	int InsertTimer(int diff_ms,EventInfo &einfo);
	int GetNextTrigerPos(int interval,TimePos &time_pos);
	int GetMS(TimePos time_pos);
	int DealTimeWheeling(std::list<EventInfo> leinfo);
private:
	//此处不是链表,是链表数组的头指针,时间轮数组
	std::list<EventInfo> *_pCallbackList = nullptr;
	std::mutex			  _mutex;
	
	//时间
	TimePos               _time_pos;
	
	//计数刻度
	int _lowCount = 0;
	int _midCount = 0;
	int _highCount = 0;

	//步长
	int _step_ms = 0;
	//定时器数量
	int _timer_count = 0;
};

//增加计时器
/*
interval必须是_step_ms的倍数
*/
template<typename Func, typename... Args>
int TimeWheel::AddTimer(int interval, Func&& func, Args&& ... args)
{
	if (interval < _step_ms || interval % _step_ms != 0 || interval >= _step_ms * _lowCount * _midCount * _highCount)
	{
		//std::cout << "time interval is invalid" << std::endl;
		return -1;
	}

	std::unique_lock<std::mutex> lock(_mutex);

	EventInfo einfo = { 0 };

	einfo.interval = interval;
	einfo.call_back = std::bind(std::forward<Func>(func), std::forward<Args>(args)...);;
	//初始化事件的时间
	einfo.time_pos.ms_pos = _time_pos.ms_pos;
	einfo.time_pos.s_pos = _time_pos.s_pos;
	einfo.time_pos.min_pos = _time_pos.min_pos;
	//随机生成id
	einfo.timer_id = GenerateTimerID();

	//插入定时器,定时器个数加一,返回定时器id
	InsertTimer(einfo.interval, einfo);
	_timer_count++;

	//std::cout << "insert timer success time_id: " << einfo.timer_id << std::endl;
	return einfo.timer_id;

}
#endif  //__TIMEWHEEL_H__

TimeWheel.cpp

#include "TimeWheel.h"

#include <iostream>
#include <windows.h>
#include <ctime>

TimeWheel::TimeWheel()
{
	memset(&_time_pos, 0, sizeof(_time_pos));
}


TimeWheel::~TimeWheel()
{
}

//初始化定时器
int TimeWheel::InitTimerWheel(int step_ms, int max_min)
{
	if (1000 % step_ms != 0)
	{
		//std::cout << "step is not property, should be devided by 1000" << std::endl;
		return -1;
	}

	//毫秒,秒,分钟。
	int msNeedCount = 1000 / step_ms;
	int sNeedCount = 60;
	int minNeedCount = max_min;

	//事件
	//初始化链表的数组,数组里的元素为链表,时间轮数组
	_pCallbackList = new std::list<EventInfo>[msNeedCount + sNeedCount + minNeedCount];
	_step_ms = step_ms;

	//步长
	_lowCount = msNeedCount;
	_midCount = sNeedCount;
	_highCount = minNeedCount;

	std::thread th([&]{
		this->DoLoop();
	});

	th.detach(); 
	return 0;
}
增加计时器
//int TimeWheel::AddTimer(int interval, std::function<void(void)>& call_back)
//{
//	if (interval < _step_ms || interval % _step_ms !=0 || interval >= _step_ms * _lowCount * _midCount * _highCount)
//	{
//		//std::cout << "time interval is invalid" << std::endl;
//		return -1;
//	}
//
//	std::unique_lock<std::mutex> lock(_mutex);
//
//	EventInfo einfo = {0};
//
//	einfo.interval = interval;
//	einfo.call_back = call_back;
//	//初始化事件的时间
//	einfo.time_pos.ms_pos = _time_pos.ms_pos;
//	einfo.time_pos.s_pos = _time_pos.s_pos;
//	einfo.time_pos.min_pos = _time_pos.min_pos;
//	//随机生成id
//	einfo.timer_id = GenerateTimerID();
//
//	//插入定时器,定时器个数加一,返回定时器id
//	InsertTimer(einfo.interval, einfo);
//	_timer_count++;
//
//	//std::cout << "insert timer success time_id: " << einfo.timer_id << std::endl;
//	return einfo.timer_id;
//
//}
//删除定时器
int TimeWheel::DeleteTimer(int timer_id)
{
	std::unique_lock<std::mutex> lock(_mutex);
	int i = 0;
	//最大事件个数
	int nCount = _lowCount + _midCount + _highCount;
	for (i = 0; i < nCount; i++)
	{
		std::list<EventInfo>& leinfo = _pCallbackList[i];
		for (auto item = leinfo.begin(); item != leinfo.end(); item++)
		{
			if (item->timer_id == timer_id)
			{
				item = leinfo.erase(item);
				return 0;
			}
		}
	}
	if (i == nCount)
	{
		//std::cout << "timer not found" << std::endl;
		return -1;
	}
	return 0;
}


int TimeWheel::DoLoop()
{
	//std::cout << "........starting loop........" << std::endl;
	static int nCount = 0;
	while (true)
	{
		std::this_thread::sleep_for(std::chrono::milliseconds(_step_ms));
		std::unique_lock<std::mutex> lock(_mutex);
		//std::cout << ".........this is " << ++nCount << "  loop........." << std::endl;
		TimePos pos = { 0 };
		TimePos last_pos = _time_pos;
		GetNextTrigerPos(_step_ms, pos);
		_time_pos = pos;

		if (pos.min_pos != last_pos.min_pos)
		{
			std::list<EventInfo>& leinfo = _pCallbackList[_time_pos.min_pos + _midCount + _lowCount];
			DealTimeWheeling(leinfo);
			leinfo.clear();
		}
		else if (pos.s_pos != last_pos.s_pos)
		{
			std::list<EventInfo>& leinfo = _pCallbackList[_time_pos.s_pos + _lowCount];
			DealTimeWheeling(leinfo);
			leinfo.clear();
		}
		else if (pos.ms_pos != last_pos.ms_pos)
		{
			std::list<EventInfo>& leinfo = _pCallbackList[_time_pos.ms_pos];
			DealTimeWheeling(leinfo);
			leinfo.clear();
		}
		else
		{
			//std::cout << "error time not change" << std::endl;
			return -1;
		}
		lock.unlock();
	}
	return 0;
}

//生成ID
int TimeWheel::GenerateTimerID()
{
	srand((int)time(0));
	int x = rand() % 0xffffffff;
	int cur_time = static_cast<int>(time(nullptr));
	return x | cur_time | _timer_count;
}

//插入定时器
int TimeWheel::InsertTimer(int diff_ms, EventInfo &einfo)
{
	TimePos time_pos = { 0 };

	GetNextTrigerPos(diff_ms, time_pos);

	//数组的每一个元素都是一个list链表
	if (time_pos.min_pos != _time_pos.min_pos)
		_pCallbackList[_lowCount + _midCount + time_pos.min_pos].push_back(einfo);
	else if (time_pos.s_pos != _time_pos.s_pos)
		_pCallbackList[_lowCount + time_pos.s_pos].push_back(einfo);
	else if (time_pos.ms_pos != _time_pos.ms_pos)
		_pCallbackList[time_pos.ms_pos].push_back(einfo);

	return 0;
}


//获得下一个结束位置的时间。
int TimeWheel::GetNextTrigerPos(int interval, TimePos &time_pos)
{
	
	int cur_ms = GetMS(_time_pos);
	int future_ms = cur_ms + interval;

	time_pos.min_pos = (future_ms / 1000 / 60) % _highCount;
	time_pos.s_pos = (future_ms % (1000 * 60)) / 1000;
	time_pos.ms_pos = (future_ms % 1000) / _step_ms;

	return 0;
}


//获取当前毫秒数
int TimeWheel::GetMS(TimePos time_pos)
{
	return _step_ms * time_pos.ms_pos + time_pos.s_pos * 1000 + time_pos.min_pos * 60 * 1000;
}


//处理事件
int TimeWheel::DealTimeWheeling(std::list<EventInfo> leinfo)
{
	for (auto item = leinfo.begin(); item != leinfo.end(); item++)
	{
		int cur_ms = GetMS(_time_pos);
		int last_ms = GetMS(item->time_pos);
		int diff_ms = (cur_ms - last_ms + (_highCount + 1) * 60 * 1000) % ((_highCount + 1) * 60 * 1000);
		if (diff_ms == item->interval)
		{
			item->call_back();

			item->time_pos = _time_pos;
			InsertTimer(item->interval, *item);
		}
		else
		{
			InsertTimer(item->interval - diff_ms, *item);
		}
	}
	return 0;

}

测试
example.cpp

#include <iostream>
#include <functional>
#include <string>
#include "TimeWheel.h"
using namespace std;

int g_count=0;

void fun100(string s)
{
	g_count++;
	cout << s<<" "<<g_count << endl;
}
void fun200()
{
	cout << "func 200" << endl;
}
void fun500()
{
	cout << "func 500" << endl;
}

void fun1500()
{
	cout << "func 1500" << endl;
}

void main()
{
	/*std::function<void()> f100 = std::bind(&fun100);
	std::function<void()> f200 = std::bind(&fun200);
	std::function<void()> f500 = std::bind(&fun500);
	std::function<void()> f1500 = std::bind(&fun1500);*/

	TimeWheel time_wheel;
	time_wheel.InitTimerWheel(1000, 5);
	int timer1 = time_wheel.AddTimer(1000, fun100,"时间轮");
	//int timer2 = time_wheel.AddTimer(200, f200);
	//int timer3 = time_wheel.AddTimer(500, f500);
	//	time_wheel.AddTimer(1500, f1500);

	bool b = true;
	int nLoop = 0;
	/*while (1)
	{
		nLoop++;
		this_thread::sleep_for(chrono::milliseconds(300));
		if (b)
		{
			time_wheel.AddTimer(1500, f1500);
			b = false;
		}
		if (nLoop == 3)
			time_wheel.DeleteTimer(timer1);
	}
*/
	system("pause");
	return;
}

时间堆定时器

锁文件 critical.h

#pragma once
#ifndef __CRITICAL_H__
#define __CRITICAL_H__


#include <Windows.h>
namespace raii 
{
	class critical 
	{
	private:
		CRITICAL_SECTION* _crit;
	public:
		critical(CRITICAL_SECTION* crit);
		critical(const critical&) = delete;
		critical& operator =(const critical&) = delete;
		~critical();
	};

	inline critical::critical(CRITICAL_SECTION* crit) 
	{
		_crit = crit;
		//进入临界区
		EnterCriticalSection(_crit);
	}

	inline critical::~critical() 
	{
		//离开临界区
		LeaveCriticalSection(_crit);
	}
}

#endif  //__CRITICAL_H__

time_heap.h

#pragma once
#ifndef __TIME_HEAP_H__
#define __TIME_HEAP_H__

/*
参考链接
https://blog.csdn.net/qq_28398301/article/details/105015492
*/

#include <future>
#include <functional>
//c++17
#include <type_traits>
#include "critical.h"

class time_heap 
{
private:
	

	// 事件信息
	class event 
	{
		friend class time_heap;
	private:
		intptr_t				_origin;	//源地址
		uint64_t				_ms;		//定时时长(按秒计算,可以是小数)
		uint32_t				_count;		//执行数
		std::function<void()>	_func;		//回调函数
	protected:
	public:
		event(intptr_t origin_, uint64_t ms_, uint32_t count_, std::function<void()>&& func_);
		event(const event&) = delete;
		event& operator =(const event&) = delete;
		~event() = default;
		// 删除函数
		void del();
	};

	// 返回数据
	template <class T>
	class result_data 
	{
		friend class time_heap;
	private:
		event*										_info;		//事件信息
		std::shared_ptr<std::packaged_task<T()>>	_pack_func;	//已包装的函数
	protected:
	public:
		bool					valid;		//有效性
		uint32_t				count;		//执行数

		result_data(uint32_t count_, std::shared_ptr<std::packaged_task<T()>> pack_func_);
		result_data(const result_data&) = delete;
		result_data& operator =(const result_data&) = delete;
		~result_data() = default;

		// 获取执行结果
		T get();
		// 删除定时器
		void del();
	};


	// 堆节点
	struct node 
	{
		uint64_t	ms;                                //结束时间
		event*		info;

		node() = default;
		node(const node&) = delete;
		node(node&& that_);
		node& operator =(const node& that_);
		node& operator =(node&& that_);
		~node() = default;
	};

	std::atomic<bool>					_death;			//结束
	CRITICAL_SECTION					_cri;			//临界区
	node*								_heap;			//最小堆
	uint32_t							_max_size;		//最大存储数
	uint32_t							_size;			//存储数
	uint64_t							_event_time;	//插入时间
	HANDLE								_event;			//事件
	static std::unique_ptr<time_heap>	_instance;		//实例指针

	// 添加节点
	void add_node();
	// 删除节点
	void del_node(uint32_t index_);
	// 删除指定下标定时器
	void del_timer(uint32_t index_);
	// 重置定时器
	void reset_timer(uint32_t index_);
	// 扩容
	void expansion();
protected:
public:
	time_heap(uint32_t max_size_ = 64);
	~time_heap();
	// 单例
	static time_heap& instance();
	// 获取距当前时间(毫秒)
	uint64_t get_ms();
	// 添加
	template<typename Func, typename... Args>
	auto add(double second_, uint32_t count_, Func&& func_, Args&& ... args_);
};


//事件构造函数
inline time_heap::event::event(intptr_t origin_, uint64_t ms_, uint32_t count_, std::function<void()>&& func_) :
	_origin(origin_),
	_ms(ms_),
	_count(count_),
	_func(std::move(func_))
{};


//事件删除函数
inline void time_heap::event::del() 
{
	auto timer = &time_heap::instance();
	raii::critical r1(&timer->_cri);
	//定时器ID
	/*
	强制类型转换
	参考
	https://blog.csdn.net/u014786409/article/details/93751093
	*/
	uint32_t index = static_cast<uint32_t>((_origin - reinterpret_cast<intptr_t>(&timer->_heap[1].ms)) / sizeof(node) + 1);
	timer->del_timer(index);
}

//返回结果构造函数
template <class T>
inline time_heap::result_data<T>::result_data(uint32_t count_, std::shared_ptr<std::packaged_task<T()>> pack_func_) :
	_info(nullptr),
	_pack_func(pack_func_),
	//有效性为真
	valid(true),
	count(count_)
{}

//返回结果:得到结果
template <class T>
inline T time_heap::result_data<T>::get() 
{
	return _pack_func->get_future().get();
}



//返回结果:删除函数
template <class T>
void time_heap::result_data<T>::del() 
{
	if (valid) {
		//将有效性置为假,删除事件
		valid = false;
		_info->del();
		return;
	}
}


/*
堆:复制构造函数
&&右值引用(临时变量)
参考
https://blog.csdn.net/kitekitebaby/article/details/72566145
*/
inline time_heap::node::node(node&& that_) 
{
	memcpy_s(this, sizeof(node), &that_, sizeof(node));
	this->info->_origin = reinterpret_cast<intptr_t>(&this->info);
	//将that置为0
	memset(&that_, 0, sizeof(node));
}

/*
堆:重载=
*/
inline time_heap::node& time_heap::node::operator =(const node& that_) 
{
	if (&that_ == this) {
		return *this;
	}
	memcpy_s(this, sizeof(node), &that_, sizeof(node));
	this->info->_origin = reinterpret_cast<intptr_t>(&this->info);
	return *this;
}

/*
堆:重载=
*/
inline time_heap::node& time_heap::node::operator =(node&& that_) 
{
	if (&that_ == this) {
		return *this;
	}
	memcpy_s(this, sizeof(node), &that_, sizeof(node));
	this->info->_origin = reinterpret_cast<intptr_t>(&this->info);
	memset(&that_, 0, sizeof(node));
	return *this;
}


/*
时间堆:删除定时器
*/
inline void time_heap::del_timer(uint32_t index_) 
{
	raii::critical r1(&_cri);
	if (_size < index_) {
		return;
	}
	//从堆里面删除index的事件和节点
	delete _heap[index_].info;
	del_node(index_);
}


/*
重置定时器;
将节点事件复制,定时时长更新。去掉老的,增加新的

*/
inline void time_heap::reset_timer(uint32_t index_) 
{
	raii::critical r1(&_cri);
	auto timer = std::move(_heap[index_]);
	//现在的时间+事件的定时时长,按秒计算
	timer.ms = get_ms() + timer.info->_ms * 1000;	//结束时间
	del_node(index_);
	_heap[_size + 1] = std::move(timer);
	add_node();
}


/*
获取时间
https://blog.csdn.net/qq_31175231/article/details/77923212
*/
inline uint64_t time_heap::get_ms() 
{
	//返回当前时间距1970-1-1 的毫秒数
	return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
}



template<typename Func, typename... Args>
auto time_heap::add(double second_, uint32_t count_, Func&& func_, Args&&... args_) 
{
	raii::critical r1(&_cri);
	auto current_size = _size + 1;
	if (current_size == _max_size) {
		expansion();
	}
	//c++11
	typedef typename std::result_of<Func(Args...)>::type  re_t;
	//c++17
	//using	re_t = typename std::invoke_result<Func, Args...>::type;	//回调函数返回类型
	//typedef typename std::invoke_result<Func, Args...>::type re_t;
	auto	task = std::make_shared<std::packaged_task<re_t()>>(std::bind(std::forward<Func>(func_), std::forward<Args>(args_)...));	//已包装回调函数指针
	std::shared_ptr<result_data<re_t>>	result = std::make_shared<result_data<re_t>>(count_, task);//返回数据
	
	uint64_t	mini_time = _heap[1].ms;//最小时间
	
	// 添加节点(添加事件,事件结束时间)
	_heap[current_size].ms = get_ms() + static_cast<int64_t>(second_) * 1000;	//结束时间
	_heap[current_size].info = new event(reinterpret_cast<intptr_t>(&_heap[current_size].ms), static_cast<uint64_t>(second_), count_, [=]() 
	{
		(*task)();
		if (--result->count == 0)
		{
			result->valid = false;
		}
		else
		{
			task->reset();
		}
	}
	);
	result->_info = _heap[current_size].info;
	add_node();
	// 决定是否唤醒
	if (mini_time != _heap[current_size].ms) {
		SetEvent(_event);
		_event_time = get_ms();
	}
	return result;
}
#endif  //__TIME_HEAP_H__

time_heap.cpp

#include "time_heap.h"
std::unique_ptr<time_heap> time_heap::_instance;

time_heap::time_heap(uint32_t max_size_) :
	_death(false),
	_heap(new node[max_size_]{}),
	_max_size(max_size_),
	_size(0),
	_event(CreateEvent(NULL, FALSE, FALSE, NULL))
{
	// 初始化临界区
	InitializeCriticalSection(&_cri);
	std::thread work_thread([&] 
	{
		DWORD wait_re, ms = INFINITE;
		std::shared_ptr<std::function<void()>> func;
		while (true) {
			wait_re = ms ? WaitForSingleObject(_event, ms) : WAIT_TIMEOUT;
			if (!_size) {
				ms = INFINITE;
				continue;
			}
			if (_death) {
				break;
			}
			auto current_ms = get_ms();
			raii::critical r1(&_cri);
			if (wait_re == WAIT_OBJECT_0) {		//事件
				ms = static_cast<DWORD>(current_ms > _heap[1].ms ? 0 : (_heap[1].ms - current_ms - (current_ms - _event_time)));
			}
			else if (wait_re == WAIT_TIMEOUT) 
			{	//超时
				//printf("超时\n");
				_heap[1].info->_func();
				if (_heap[1].info->_count == INFINITE) 
				{
					reset_timer(1);
				}
				else if (--_heap[1].info->_count == 0)
				{
					del_timer(1);
				}
				else {
					reset_timer(1);
				}
				ms = static_cast<DWORD>(_size > 0 ? _heap[1].ms - current_ms : INFINITE);
			}
			else if (wait_re == WAIT_FAILED) {	//失败
				printf("失败: %I64d\n", current_ms);
			}
		}
	});
	work_thread.detach();
}

time_heap::~time_heap() 
{
	_death = true;
	{
		raii::critical r1(&_cri);
		// 退出工作线程
		SetEvent(_event);
		for (; _size > 0; --_size) {
			delete _heap[_size].info;
		}
		delete[] _heap;
	}
	DeleteCriticalSection(&_cri);
}

void time_heap::add_node() 
{
	raii::critical r1(&_cri);
	uint32_t index1 = ++_size, index2 = index1 >> 1;
	while (index1 > 1 && _heap[index2].ms > _heap[index1].ms) {
		std::swap(_heap[index1], _heap[index2]);
		index1 = index2;
		index2 >>= 1;
	}
}

/*
堆排序
参考链接
https://blog.csdn.net/wangrenhaioylj/article/details/108565134

*/

void time_heap::del_node(uint32_t index_) 
{
	raii::critical r1(&_cri);
	if (_size < index_) 
	{
		return;
	}
	// 向下调整
	if (_heap[_size].ms > _heap[index_].ms) 
	{
		uint32_t index1 = index_, index2 = index1 << 1;
		while (index2 < _size) 
		{
			if (_heap[index2].ms > _heap[index2 + 1].ms) 
			{
				++index2;
			}
			if (_heap[_size].ms > _heap[index2].ms) 
			{
				_heap[index1] = _heap[index2];
				index1 = index2;
				index2 <<= 1;
			}
			else 
			{
				break;
			}
		}
		_heap[index1] = _heap[_size];
		memset(&_heap[_size], 0, sizeof(node));
	}
	// 向上调整
	else if (_heap[_size].ms < _heap[index_].ms) 
	{
		uint32_t index1 = index_ >> 1, index2 = _size;
		while (_heap[index1].ms > _heap[index2].ms) 
		{
			std::swap(_heap[index1], _heap[_size]);
			index2 = index1;
			index1 >>= 1;
		}
		_heap[index_] = _heap[_size];
		memset(&_heap[_size], 0, sizeof(node));
	}
	// 不做调整
	else 
	{
		_heap[index_] = _heap[_size];
		memset(&_heap[_size], 0, sizeof(node));
	}
	if (--_size > 0) 
	{
		_event_time = get_ms();
		SetEvent(_event);
	}
}

void time_heap::expansion() 
{
	auto size = sizeof(node) * _max_size;
	node* new_heap = new node[_max_size <<= 1]{};
	raii::critical r1(&_cri);
	memcpy_s(new_heap, size << 1, _heap, size);
	delete[] _heap;
	_heap = new_heap;
}


/*
参考
https://blog.csdn.net/ynshi57/article/details/108083019
https://www.cnblogs.com/xuhuajie/p/11647164.html

*/
time_heap& time_heap::instance() 
{
	static std::once_flag s_flag;
	std::call_once(s_flag, [&]() 
	{
		_instance.reset(new time_heap);
	}
	);
	return *_instance;
}

使用example.cpp

#include "time_heap.h"


/*
使用说明:


在删除定时器之前(务必不要删除,否则只执行一次)

初始化
auto &timer = time_heap::instance();
加入定时器,参数:秒(可以填小数,转换为毫秒),指定执行次数,函数,函数的参数。
auto timer1 = timer.add(second, count,test_1, g_index);

//得到返回结果,返回为void的 不需要执行,否则出错
if (timer1->valid) {
auto result = timer1->get();
}

删除
timer1->del();
*/

int g_index = 0;

int test_1(int index)
{
	g_index++;
	printf("%d\n", g_index);
	return 0;
}


void main()
{
	auto &timer = time_heap::instance();
	//定时时长(单位:秒,由于是double可以传入0.05这样的数字,会自动转为毫秒)
	double second = 0.001;
	//执行次数
	uint32_t count = 1001;	

	//timer.add函数的返回值是一个std::shared_ptr对象。不用手动销毁
	//auto timer1 = timer.add(second, count, [&](int index) {
	//	printf("%d\n",index);
	//	return index;
	//}
	//, 7);	//不定参,可以使用任意类型个数的参数
	
	auto timer1 = timer.add(second, count,test_1, g_index);

	//获取事件函数返回值(若未事件未执行完成将堵塞)
	//auto result = timer1->get();
	//安全的获取事件函数返回值(若未事件未执行完成将堵塞,超过count次get完成后再次get将cash)
	/*
	返回是void的话,不需要执行。
	*/
	if (timer1->valid) {
		auto result = timer1->get();
	}
	//printf("%d\n", result);
	//timer1->del();		        //删除定时事件
	//system("pause");
	getchar();
	return;
}
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值