Windows C++服务器 全局秒级高效计时处理器

c++11 支持lambda 回调

支持无锁多线程操作,cancel 返回true时有一定概率无法取消func的执行

.h文件

#pragma once

#include <map>
#include <process.h>
#include <windows.h>
#include <functional>
#include <atomic>

void Polling(void* ptr);

struct _GTimer_Arg
{
	int time=-1;
	std::function<void*(void*)> func=NULL;
	void* arg = NULL;//此处必须指向堆
	int status = 1;
};

class GTimer
{
	int _thread;
	std::map<int, _GTimer_Arg> _map;
	std::atomic_uint32_t _id ;
public:
	GTimer()
	{
		_beginthread(Polling, 0, &_map);
	}

	unsigned int Set(_GTimer_Arg unit)
	{
		_map[_id] = unit;
		return _id++;
	}

	int Get(int id)
	{
		if (_map.count(id))
		{
			return _map[id].time;
		}
		return -1;
	}
	
	bool TryCancel(int id)//成功返回true,回调不会执行,否则false
	{
		if (_map.count(id)&&_map[id].time>0)
		{
			_map[id].status = 2;
			return true;
		}
		return false;
	}
};



.cpp


#include "gtimer.h"

void Polling(void* ptr)
{
	std::map<int, _GTimer_Arg>* _map = (std::map<int, _GTimer_Arg>*)ptr;
	while (true)
	{
		for (auto iter = _map->begin(); iter != _map->end();)
		{	iter->second.time--;
			if(iter->second.status==2)
			{
				if (iter->second.arg != NULL)
				{
					delete iter->second.arg;
					iter->second.arg = NULL;
				}
				_map->erase(iter++);
				continue;
			}
			
			if (iter->second.time == 0)
			{
				if(iter->second.func!=NULL)
				iter->second.func(iter->second.arg);

				if (iter->second.arg != NULL)
				{
					delete iter->second.arg;
					iter->second.arg = NULL;
				}
				_map->erase(iter++);
			}
			else
			{
				++iter;
			}
		}
		Sleep(1000);
	}
}



此版本为线程安全版且增添键模板,线程进入for之前,cancel可立即取消


atomic_lock.h

#pragma once
#include <atomic>
#include <windows.h>

class Atomic_Lock
{
	std::atomic_bool _lock = false;
	bool _lockExp = true;
	bool _unlockExp = false;
	int status = 1;
public:
	void Lock()
	{
		while (!atomic_compare_exchange_weak(&_lock, &_unlockExp, _lockExp))
		{
			Sleep(1);
		}
	}
	void UnLock()
	{
		_lock = false;
	}
	void Discard()
	{
		status = 0;
	}
	int GetStatus() const
	{
		return status;
	}
};



safeMap.h


#pragma once
#include <map>
#include "atomic_lock.h"
using namespace std;
template <class K,class V>
class safeMap:public map<K,V>
{
	Atomic_Lock _al;
public:
	safeMap()
	{

	}
	void Lock()
	{
		_al.Lock();
	}
	void UnLock()
	{
		_al.UnLock();
	}
};


gtimer.h

#pragma once

#include <process.h>
#include <windows.h>
#include <functional>
#include "safeMap.h"
template <typename T>
void Polling(void* ptr)
{
	GTimer<T>* gt = (GTimer<T>*)ptr;
	gt->Dealing();
}

struct _GTimer_Arg
{
	int time=-1;
	std::function<void*(void*)> func=NULL;
	void* arg = NULL;
};

template <typename K>
class GTimer
{
	int _thread;
	safeMap<K, _GTimer_Arg> _map;
public:
	void Dealing()
	{
		while (true)
		{
			_map.Lock();
			for (auto iter = _map.begin(); iter != _map.end();)
			{
				iter->second.time--;
				if (iter->second.time == 0)
				{
					if (iter->second.func != NULL)
						iter->second.func(iter->second.arg);

					if (iter->second.arg != NULL) {
						int arg_num = _msize(iter->second.arg) / 8;
						if (arg_num > 1)
						{
							void** args = (void**)iter->second.arg;
							for (int i = 0; i < arg_num; i++)
							{
								delete args[i];
							}
						}
						delete iter->second.arg;
					}
					_map.erase(iter++);
				}
				else
				{
					++iter;
				}
			}
			_map.UnLock();
			Sleep(1000);
		}
	}
	GTimer()
	{
		_thread=_beginthread(Polling<K>, 0, this);
	}

	void Set(K id,_GTimer_Arg unit)
	{
		_map.Lock();
		if(_map.count(id))
		{
			_GTimer_Arg& ga=_map[id];
			if(ga.arg != NULL) {
				int arg_num = _msize(ga.arg) / 8;
				if (arg_num > 1)
				{
					void** args = (void**)ga.arg;
					for (int i = 0; i < arg_num; i++)
					{
						delete args[i];
					}
				}
				delete ga.arg;
			}
		}
		_map[id] = unit;
		_map.UnLock();
	}

	int Get(K id)
	{
		if (_map.count(id))
		{
			return _map[id].time;
		}
		return -1;
	}


	void Cancel(K id)
	{
		_map.Lock();
		if (_map.count(id))
		{
			_GTimer_Arg& ga = _map[id];
			if (ga.arg != NULL) {
				int arg_num = _msize(ga.arg) / 8;
				if (arg_num > 1)
				{
					void** args = (void**)ga.arg;
					for (int i = 0; i < arg_num; i++)
					{
						delete args[i];
					}
				}
				delete ga.arg;
			}
		}
		_map.erase(id);
		_map.UnLock();
	}
};









  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值