个人项目中抽提的一些工具类

本文介绍了一个跨Windows和Linux平台的工具类库kCores,包含Vector、Map、Queue三大容器,Mutex锁,Signal信号量,Engine线程基类及TaskRunner任务机。深入探讨了各类组件的设计原理与实现细节。
摘要由CSDN通过智能技术生成
/*************************************************************************
** Copyright(c) 2016-2020  hicker - 薛凯
** All rights reserved.
** Name		: kCores.h
** Desc		: 从个人项目中抽提出的一些常用工具类,跨windows和linux
**			: 三大容器Vector/Map/Queue,锁Mutex,信号量Signal,线程基类Engine,任务机TaskRunner
** Author	: hicker@2017-5-27 10:27:25
*************************************************************************/


#ifndef __KCORES_H__
#define __KCORES_H__

#define __WIN32__

namespace kCores
{
	
	/*************************************************************************
	** Name		: 仿java终结类
	** Desc		: 仿java的final关键字,使用方法:虚继承之
	** Author	: hicker@2017-5-27 10:27:25
	*************************************************************************/
	template <class T>
	class Final
	{
		friend T;
	private:
		Final() {}
		Final(const Final&) {}
	};

	
	/*************************************************************************
	** Desc		: Find 在[it0,it1)内查找,查找不到返回it1
	** Param	: [in] it0
	** Param	: [in] it1
	** Param	: [in] v
	** Return	: 查找不到返回it1
	** Author	: hicker@2016-12-31 19:56:11
	*************************************************************************/
	template<class _Iter_, class _V_>
	static _Iter_ Find(_Iter_ it0, _Iter_ it1, _V_ v)
	{
		for (it0; it0 != it1; ++it0)
		{
			if (it0 == v)
				return it0;
		}
		return it1;
	}

	template <class T>
	class Vector
	{
	public:
		template <class N>
		struct Node
		{
			Node(const N &n) :value(n), next(0), prev(0){}
			Node *next, *prev;
			N value;
		};

		class Iterator
		{
		public:
			Iterator(Node<T>* pNode){ m_pNode = pNode; }
			T& operator* (void) const { return m_pNode->value; }
			T* operator-> (void) const { return &m_pNode->value; }
			// 两种“==”都只比较value
			bool operator==(Iterator const& it) const
			{
				// 特殊相等:Begin强制与End相等
				if (m_pNode == NULL && !it.m_pNode->prev)
					return true;
				else if (m_pNode->next && !it.m_pNode->next)// 特殊不相等:非End强制与End不相等
					return false;
				return m_pNode->value == *it;
			}
			bool operator==(T const& n) const { return m_pNode->value == n; }
			bool operator!= (Iterator const& it) const { return !(*this == it); }

			Iterator& operator+ (int i) { while (i--)(*this)++; return *this; }
			Iterator& operator- (int i) { while (i--)(*this)--; return *this; }

			// 前置++
			Iterator& operator++ (void)
			{
				m_pNode = m_pNode->next;
				return *this;
			}

			// 后置++
			Iterator& operator++ (int)
			{
				Iterator &old = *this;
				++*this;
				return old;
			}
			// 前置--
			Iterator& operator-- (void)
			{
				m_pNode = m_pNode->prev;
				return *this;
			}
			// 后置--
			Iterator& operator-- (int)
			{
				Iterator &old = *this;
				--*this;
				return old;
			}

		private:
			Node<T>* m_pNode;
			friend class Vector;
		};

		Vector() :m_nSize(0), m_pHead(0){ m_pTail = new Node<T>(T()); }
		Vector(const Vector<T> &v) :m_nSize(0), m_pHead(0){ m_pTail = new Node<T>(T());  (*this) = v; }
		virtual ~Vector(){ Clear(); delete m_pTail; }
		Vector<T>& operator=(const Vector<T>& v)
		{
			if (this == &v) return *this;
			this->Clear();
			for (int i = 0; i < v.Size(); i++)
				this->Insert(i, v[i]);
			return (*this);
		};

		int Size() const{ return m_nSize; }
		bool Empty() const{ return m_nSize ? true : false; }

		void PushBack(const T& t){ Insert(-1, t); };
		T& PopBack(){ return Erase(Begin() + (m_nSize - 1)).m_pNode->value; };

		T& operator[](int idx) const { return find(idx)->value; };
		T& At(int idx){ return (*this)[idx]; }

		/*************************************************************************
		** Desc		: Insert
		** Param	: [in] idx 欲插入的元素索引,当为(-1)或(>=m_nSize)时,添加到末尾
		** Return	: 返回插入元素的迭代器
		** Author	: hicker@2017-6-24 11:21:01
		*************************************************************************/
		Iterator& Insert(int idx, const T& t)
		{
			if (m_nSize == 0)
			{
				m_pHead = new Node<T>(t);
				m_pTail->prev = m_pHead;
				m_pHead->next = m_pTail;
				m_nSize++;
				return Begin();
			}

			if (idx < 0 || idx>m_nSize)idx = m_nSize;

			if (idx == m_nSize)
			{
				// 末尾插
				Node<T> *p = find(idx - 1);
				
				p->next = new Node<T>(t);
				p->next->prev = p;
				p->next->next = m_pTail;
				m_pTail->prev = p->next;
			}
			else
			{
				// 前插
				Node<T> *p = find(idx);
				if (!p->prev)
				{
					p->prev = new Node<T>(t);
					p->prev->next = p;
					m_pHead = p->prev;
				}
				else
				{
					p->prev->next = new Node<T>(t);
					p->prev->next->prev = p->prev;
					p->prev->next->next = p;
					p->prev = p->prev->next;
				}
			}
			m_nSize++;
			
			return kCores::Find(Begin(), End(), t);
		}

		/*************************************************************************
		** Desc		: Erase 由caller保证it合法性,否则异常
		** Param	: [in] it 欲擦除的元素迭代器
		** Return	: 返回已被擦除元素
		** Author	: hicker@2017-6-24 11:21:01
		*************************************************************************/
		Iterator& Erase(Iterator& it)
		{
			if (it.m_pNode == m_pHead)
			{
				if (it.m_pNode->next == m_pTail)
				{
					m_pHead = NULL;
					m_pTail->prev = m_pHead;
				}
				else
				{
					m_pHead = it.m_pNode->next;
					m_pHead->prev = NULL;
				}
			}
			else
			{
				it.m_pNode->next->prev = it.m_pNode->prev;
				it.m_pNode->prev->next = it.m_pNode->next;
			}

			delete it.m_pNode;
			m_nSize--;

			return it;
		}

		void Clear()
		{
			while (m_pHead)
				Erase(Begin());
			/*m_pHead = NULL;
			m_pTail->prev = m_pHead;
			m_nSize = 0;*/
		}

		Iterator Begin(){ return Iterator(m_pHead); }
		Iterator End(){ return Iterator(m_pTail); }

	private:
		// hicker@2017-6-25 20:17:16 coding 根据索引找,是否有必要添加一个根据迭代器\元素值找?
		Node<T>* find(int idx) const
		{
			Node<T> *p = m_pHead;
			while ((idx--)>0)p = p->next;
			return p;
		}

		int m_nSize;
		Node<T> *m_pHead;
		Node<T> *m_pTail;
	};


	/*************************************************************************
	** Desc		: 队列
	** Author	: hicker@2016-12-31 19:56:11
	*************************************************************************/
	template <typename T>
	class Queue
	{
	public:
		Queue()
		{
			Node<T> *node = new Node<T>();
			node->data = NULL;
			node->next = NULL;
			qfront = qrear = node;
		}
		bool Empty() const
		{
			return (qfront == qrear);
		};
		void Pop()
		{
			if (!Empty())
			{
				Node<T> *p = qfront->next;
				qfront->next = p->next;
				if (p == qrear)
					qrear = qfront;
				delete p;
				p = NULL;
			}
		};
		T Front()
		{
			if (!Empty())
			{
				Node<T> *p = qfront->next;
				return p->data;
			}
			return T();
		};
		T Back()
		{
			if (!Empty())
				return qrear->data;
			return T();
		};
		void Push(const T &t)
		{
			Node<T> *node = new Node<T>;
			node->data = t;
			node->next = NULL;
			qrear->next = node;
			qrear = node;
		};
		int Size() const
		{
			Node<T> *p = qfront;
			if (Empty())
				return 0;
			else
			{
				int i = 1;
				while (p->next != qrear)
				{
					p = p->next;
					i++;
				}
				return i;
			}
		};
	private:
		template <typename N>
		struct Node
		{
			Node<N> *next;
			N data;
		};

		Node<T> *qfront, *qrear;
	};


	/*************************************************************************
	** Desc		: map
	** Author	: hicker@2016-12-31 19:56:11
	*************************************************************************/
	template<typename K, typename V>
	class Map
	{
	public:
		class Node
		{
		public:
			Node(K k, V const& v) :prev(NULL), next(NULL), first(k), second(v){}
			K first;//key
			V second;// value
		private:
			Node* prev;
			Node* next;
			friend class Map;
		};
		class Iterator
		{
		public:
			Iterator(Node* pNode){ m_pNode = pNode; }
			// hicker@2017-6-24 20:49:38 coding 比较m_pNode还是m_pNode->first????????????
			bool operator== (Iterator const& it) const {
				// 特殊相等:Begin强制与End相等
				if (m_pNode == NULL && !it.m_pNode->prev)
					return true;
				return (m_pNode == it.m_pNode);
			}
			bool operator== (K const& k) const {
				return m_pNode->first == k;
			}
			bool operator!= (Iterator const& it) const
			{
				return !(*this == it);
			}
			Iterator& operator+ (int i)
			{
				while (i--)(*this)++;
				return *this;
			}
			Iterator& operator- (int i)
			{
				while (i--)(*this)--;
				return *this;
			}
			Iterator& operator++ (void)
			{
				m_pNode = m_pNode->next;
				return *this;
			}
			Iterator const operator++ (int)
			{
				Iterator old = *this;
				++*this;
				return old;
			}
			Iterator& operator-- (void)
			{
				m_pNode = m_pNode->prev;
				return *this;
			}
			Iterator const operator-- (int)
			{
				Iterator old = *this;
				--*this;
				return old;
			}
			Node& operator* (void) const { return *m_pNode; }
			Node* operator-> (void) const { return m_pNode; }

		private:
			Node* m_pNode;
			friend class Map;
		};

		Map() :m_pHead(NULL), m_nSize(0){ m_pTail = new Node(K(), V()); }
		virtual ~Map(){ Clear();  delete m_pTail; }
		Map(Map<K, V>& m) :m_pHead(NULL), m_nSize(0){ m_pTail = new Node(K(), V()); (*this) = m; }
		Map<K, V>& operator=(Map<K, V>& m)
		{
			if (this != &m)
			{
				Clear();
				for (Iterator it = m.Begin(); it != m.End(); ++it)
					(*this)[it->first] = it->second;
			}
			return *this;
		}

		Iterator Begin(){ return Iterator(m_pHead); }
		Iterator End(){ return Iterator(m_pTail); }
		int Size(){ return m_nSize; }

		//如果已存在,则直接返回
		Iterator Insert(K key, V val)
		{
			Node* pNode = find(key);
			if (NULL == pNode)
			{
				(*this)[key] = val;
			}
			return pNode;
		}

		//如果不存在,则先创建再插入
		V& operator[](K key)
		{
			Node* pNode = find(key);
			if (NULL == pNode)
			{
				pNode = new Node(key, V());
				pNode->prev = m_pTail->prev;
				pNode->next = m_pTail;
				if (m_pTail->prev)
					m_pTail->prev->next = pNode;
				else
					m_pHead = pNode;
				m_pTail->prev = pNode;
				m_nSize++;
			}
			return pNode->second;
		}

		//删除指定的元素值
		Iterator Erase(K key)
		{
			Node *pNode = find(key);
			if (pNode)
			{
				if (pNode == m_pHead)
				{
					if (pNode->next == m_pTail)
					{
						m_pHead = NULL;
						m_pTail->prev = m_pHead;
					}
					else
					{
						m_pHead = pNode->next;
						m_pHead->prev = NULL;
					}
				}
				else
				{
					pNode->next->prev = pNode->prev;
					pNode->prev->next = pNode->next;
				}
				delete pNode;
				m_nSize--;
			}
			return Find(Begin(), End(), key);
		}

		// 判等函数的通用版本
		//bool Equal(V const& a,V const& b) const {return a == b;}

		void Clear()
		{
			while (m_pHead)
				Erase(m_pHead->first);
		}
	private:
		// 查找有没有key值的结点存在
		Node* find(K& key)
		{
			for (Node* pNode = m_pHead; pNode && pNode != m_pTail; pNode = pNode->next)
			{
				if (pNode->first == key)
					return pNode;
			}
			return NULL;
		}
		Node* m_pHead;
		Node* m_pTail;
		int m_nSize;
	};

#if 0
	// 特化判等
	template<>
	bool Map<char const*>::Equal(char const* const& a,
		char const* const& b) const {
		return !strcmp(a, b);
	}

	template<>
	char& Map<char>::operator[](int key){
		// 查找是否存在
		Node* pn = findkey(key);
		// 不存在就构造一个新的默认值
		if (NULL == pn){
			char  pdata = '\0';
			pn = Insert(key, pdata);
		}
		return pn->second;
	}
	// 特化[]
	template<>
	char const*& Map<char const*>::operator[](int key){
		// 查找是否存在
		Node* pn = findkey(key);
		// 不存在就构造一个新的默认值
		if (NULL == pn){
			char*  pdata = "";
			pn = Insert(key, pdata);
		}
		return pn->second;
	}

	template<>
	short& Map<short>::operator[](int key){
		// 查找是否存在
		Node* pn = findkey(key);
		// 不存在就构造一个新的默认值
		if (NULL == pn){
			short  pdata = 0;
			pn = Insert(key, pdata);
		}
		return pn->second;
	}
	template<>
	int& Map<int>::operator[](int key){
		// 查找是否存在
		Node* pn = findkey(key);
		// 不存在就构造一个新的默认值
		if (NULL == pn){
			int  pdata = 0;
			pn = Insert(key, pdata);
		}
		return pn->second;
	}

	template<>
	long& Map<long>::operator[](int key){
		// 查找是否存在
		Node* pn = findkey(key);
		// 不存在就构造一个新的默认值
		if (NULL == pn){
			long  pdata = 0;
			pn = Insert(key, pdata);
		}
		return pn->second;
	}

	template<>
	float& Map<float>::operator[](int key){
		// 查找是否存在
		Node* pn = findkey(key);
		// 不存在就构造一个新的默认值
		if (NULL == pn){
			float  pdata = 0.0;
			pn = Insert(key, pdata);
		}
		return pn->second;
	}

	template<>
	double& Map<double>::operator[](int key){
		// 查找是否存在
		Node* pn = findkey(key);
		// 不存在就构造一个新的默认值
		if (NULL == pn){
			double  pdata = 0.0;
			pn = Insert(key, pdata);
		}
		return pn->second;
	}
#endif

class Mutex
{
public:
	Mutex()
	{
#ifdef __WIN32__
		m_mutex = (int)CreateMutex(NULL, FALSE, NULL);
#elif defined __LINUX__
		if (pthread_mutex_init(&m_mutex, NULL)<0)
		{
			perror("pthread_mutex_init");
			return;
		}
#endif
	};

	virtual ~Mutex()
	{
#ifdef __WIN32__
		CloseHandle((HANDLE)m_mutex);
#elif defined __LINUX__
		pthread_mutex_destroy(&m_mutex);
#endif
	};

	BOOL Lock()
	{
#ifdef __WIN32__
		return WAIT_OBJECT_0 == WaitForSingleObject((HANDLE)m_mutex, INFINITE);
#elif defined __LINUX__
		return 0 == pthread_mutex_lock(&m_mutex);
#endif
	};

	BOOL UnLock()
	{
#ifdef __WIN32__
		return 0 != ReleaseMutex((HANDLE)m_mutex);
#elif defined __LINUX__
		return 0 == pthread_mutex_unlock(&m_mutex);
#endif
	};

private:
#ifdef __WIN32__
	int m_mutex;
#elif defined __LINUX__
	pthread_mutex_t m_mutex;
#endif
};
	
class Signal
{
public:
	Signal()
	{
#ifdef __WIN32__
		m_signal = (int)CreateEvent(NULL, FALSE, FALSE, NULL);
#elif __LINUX__
		for (int i = 0; i<255; i++)
		{
			m_signal = semget(ftok(".", i), 1, 0666 | IPC_CREAT | IPC_EXCL);
			if (-1 != m_signal)
				break;
		}
		if (m_signal == -1)
		{
			perror("semget failed!\n");
			return;
		}
		union semun sem_union;
		sem_union.val = 0; // 初始化为0,表示首次调用Wait会阻塞,1表示首次调用Wait不阻塞
		if (semctl(m_signal, 0, SETVAL, sem_union))
		{
			perror("semctl error!\n");
		}
#endif	
	};

	virtual ~Signal()
	{
#ifdef __WIN32__
		CloseHandle((HANDLE)m_signal);
#elif __LINUX__
		union semun sem_union;
		if (semctl(m_signal, 0, IPC_RMID, sem_union))
			printf("Failed to delete semaphore\n");
#endif
	};

	virtual int Wait()
	{
#ifdef __WIN32__
		return WAIT_OBJECT_0 != WaitForSingleObject((HANDLE)m_signal, INFINITE);
#elif __LINUX__
		struct sembuf sem_b = { 0/*信号量编号*/, -1/*V操作*/, SEM_UNDO };
		if (semop(m_signal, &sem_b, 1) == -1)
		{
			printf("semaphore_p failed\n");
			return 0;
		}
		return 1;
#endif
	};

	virtual int Notify()
	{
#ifdef __WIN32__
		return 0 != SetEvent((HANDLE)m_signal);
#elif __LINUX__
		struct sembuf sem_b = { 0/*信号量编号*/, 1/*V操作*/, SEM_UNDO };
		if (semop(m_signal, &sem_b, 1) == -1)
		{
			printf("semaphore_v failed\n");
			return 0;
		}
		return 1;
#endif
	};

private:
	int m_signal; // linux sem_id
	union semun{
		int val;
		struct semid_ds *buf;
		unsigned short *arry;
	};
};

class Engine
{
public:
	template<class cls>
	Engine(cls pThis)
	{
		m_pObj = (int)pThis;
		m_pSignal = new Signal();
		m_pMutex = new Mutex();
		memset(m_vecInfo, 0, sizeof(m_vecInfo));
		m_tmpidx = 0;
	};
	virtual ~Engine()
	{
		delete m_pMutex;
		delete m_pSignal;
	};

	template<class int_func_int>
	/*************************************************************************
	** Desc		: 启动一个线程,返回其id
	** Param	: [in] idx 线程唯一索引,范围[0,31]
	** 			: [in] p_exec 线程函数地址,自身/子类/父类均必须不能是virtual,
	**					且函数声明一定符合 int(*)(int),否则引发错误:
	**					Run-Time Check Failure #0 - The value of ESP was not...
	**			  [in] i_exec
	**			  [in] nStackSize
	**			  [in] nPriority
	** Return	: ≤0 表示失败,否则返回当前线程state
	** Author	: hicker@2017-2-26 13:03:10
	*************************************************************************/
	// hicker@2017-6-29 23:23:25 coding 第2参数需优化
	//typedef int(Engine::*pfn)(int);
	int Ignite(int idx, int_func_int p_exec, int i_exec, int nStackSize = 0, int nPriority = 0)
	{
		int iRet = 0;
		if (!m_pMutex->Lock())
		{
			printf("m_pMutex->Lock failed!!\n");
			return iRet;
		}
		do
		{
			iRet = m_vecInfo[idx].state1;
			if (idx<0 || idx>(sizeof(m_vecInfo) / sizeof(m_vecInfo[0])) || (iRet && iRet != 4))
				break;

			// hicker@2018-6-2 23:49:10 coding win与lux编译器区别,以后有时间需继续搞清Engine的细节问题
#ifdef __WIN32__
			m_vecInfo[idx].pthis = m_pObj;
#elif defined __LINUX__
			m_vecInfo[idx].pthis = (int)this;
#endif
#if 1
			m_vecInfo[idx].p_exec = (int(Engine::*)(int))p_exec;
#else
			m_vecInfo[idx].p_exec = union_cast<int(Engine::*)(int)>(p_exec);
#endif
			m_vecInfo[idx].i_exec = i_exec;
			m_tmpidx = idx;
			iRet = 0;
#ifdef __WIN32__ 
			m_vecInfo[idx].handle = (int)CreateThread(NULL, nStackSize, (LPTHREAD_START_ROUTINE)Engine::__Cylinder,
				(LPVOID)this, 0, (LPDWORD)&m_vecInfo[idx].n_tid);
			if (m_vecInfo[idx].handle < 0 || !SetThreadPriority((HANDLE)m_vecInfo[idx].handle, nPriority))
				break;
#elif __LINUX__
			int handle = pthread_create((pthread_t*)&m_vecInfo[idx].n_tid, NULL, Engine::__Cylinder, this);
			if (handle != 0)
				break;
#endif

			m_vecInfo[idx].state0 = 1;
			m_vecInfo[idx].state1 = 1; // hicker@2017-6-1 22:52:35 coding 未良好处理!!!
			iRet = m_vecInfo[idx].state1;
			m_pSignal->Wait();
		} while (0);
		if (idx<0 || idx>(sizeof(m_vecInfo) / sizeof(m_vecInfo[0]) - 1)) iRet = 0;
		m_pMutex->UnLock();
		return iRet;
	};

	// nTid=0时,针对所有线程
	virtual void Stall(int idx, int nMsec = 3000)
	{
		m_vecInfo[idx].state0 = 0;
		for (int i = 0; i < nMsec; i+=50)
		{
#ifdef __WIN32__
			Sleep(50);
#elif defined __LINUX__
			usleep(50*1000);
#endif
			if (!m_vecInfo[idx].state1) return;
		}
#ifdef __WIN32__
		TerminateThread((HANDLE)m_vecInfo[idx].handle, -1);
#elif defined __LINUX__
		pthread_cancel(m_vecInfo[idx].n_tid);
#endif
		memset(&m_vecInfo[idx], 0, sizeof(m_vecInfo[0]));
	};

	virtual void Suspend(int idx)
	{
#ifdef __WIN32__
		SuspendThread((HANDLE)m_vecInfo[idx].handle);
#elif defined __LINUX__
#endif
	};
	virtual void Resume(int idx)
	{
#ifdef __WIN32__
		ResumeThread((HANDLE)m_vecInfo[idx].handle);
#elif defined __LINUX__
#endif
	};

	// 
	int TryState(int idx)
	{
		return m_vecInfo[idx].state0;
	}

	int GetState(int idx)
	{
		return m_vecInfo[idx].state1;
	}
	//virtual void Join();
	//virtual int Work(int nWtId) = 0;

	static int GetCurrentId()
	{
#ifdef __WIN32__
		// 虽然GetCurrentThreadId返回0,但直接给0值好像会导致PostThreadMessage异常
		return GetCurrentThreadId();
#elif defined __LINUX__
		return pthread_self();
#endif  
	};

protected:
	int GetFreeId()
	{
		if (!m_pMutex->Lock())
			return -1;
		int iRet = -1;
		for (int i = 0; i < (sizeof(m_vecInfo) / sizeof(m_vecInfo[0])); i++)
		{
			if (m_vecInfo[i].state1 == 0 && m_vecInfo[i].state1 != 4)
			{
				m_vecInfo[i].state1 = 4;
				iRet = i;
				break;
			}
		}
		m_pMutex->UnLock();
		return iRet;
	};

private:
	static void* __Cylinder(void *p)
	{
		Engine *pThis = (Engine*)p;
		int idx = pThis->m_tmpidx;
		Info info = pThis->m_vecInfo[idx];
		pThis->m_pSignal->Notify();
#if 0
		(pThis->*p_exec)(idx); // 起不到多态的作用,实测发现某些类或函数继承关系导致this指针不准确
#else
		(((Engine*)info.pthis)->*(info.p_exec))(info.i_exec);
#endif
		memset(&pThis->m_vecInfo[idx], 0, sizeof(pThis->m_vecInfo[0]));
		return 0;
	};

private:
	struct Info
	{
		int pthis; // 保存真正子类this指针
		int n_tid;
		int handle;
		int state0; // 应处状态【调用Stall后会置0】:0-stop, 1-start, 2-pause, 3-switch, 4-be GetFreeId()
		int state1; // 实际状态:0-stop, 1-start, 2-pause, 3-switch, 4-be GetFreeId()
		int(Engine::*p_exec)(int);
		int i_exec; // p_exec的参数
	};
	int m_pObj;
	Info m_vecInfo[32];
	int m_tmpidx; // 临时变量
	//Vector<__WorkArgs> m_vecWorkArgs;
	//Signal *m_pSignal1;
	Signal *m_pSignal;
	Mutex *m_pMutex;
};


template<class T>
class TaskRunner:public kCores::Engine
{
public:
	struct TaskInfo
	{
		TaskInfo(int iType, int (T::*pfnProc)(int, int, int, char*, long), int arg0, int arg1, char *arg2, long tmOffset = 0)
		{
			static int _id_ = 1;
			this->id = _id_++;
			this->iType = iType;
			this->pfnProc = pfnProc;
			this->arg0 = arg0;
			this->arg1 = arg1;
			if (arg2) strncpy(arg2, arg2, sizeof(this->arg2));
			this->trigTick = xUtils::SysUtil::GetCurrentTick() + tmOffset;
		}
		int (T::*pfnProc)(int, int, int, char*);
		int id;
		int iType;
		int arg0;
		int arg1;
		char arg2[4096];
		unsigned long trigTick;
	};

public:
	TaskRunner(T *pHandler) :Engine(this)
	{
		ID_CYLRUNNER = GetFreeId();
		m_pHandler = pHandler; 
		m_bStop = true;
		m_bRunning = false;
	};

	bool Start()
	{
		m_bStop = false;
		m_bRunning = false;
		Ignite(ID_CYLRUNNER, /*union_cast<int>(*/&TaskRunner::Runner/*)*/, 0);
		return true;
	}

	bool Stop()
	{
		m_bStop = true;
		Stall(ID_CYLRUNNER);
		return true;
	}

	int Load(int (T::*pFunc)(int, int, int, char*), int arg0, int arg1, char *str4k, long tmOffset = 0)
	{
		TaskInfo *pTaskInfo = new TaskInfo(pFunc, arg0, arg1, str4k, tmOffset);
		m_vecTaskInfo.PushBack(pTaskInfo);

		return pTaskInfo->id;
	}

	// 若id<1则根据iType卸载,若id>0则根据id卸载并忽略iType,返回卸载的任务个数
	int Unload(int id, int iType)
	{
		int iCount = 0;
		for (typename kCores::Vector<TaskInfo*>::Itertor it = m_vecTaskInfo.Begin(); it != m_vecTaskInfo.End();)
		{
			if (id<1 && iType>0)
			{
				if (it->iType == iType)
				{
					m_vecTaskInfo.Erase(it);
					it = m_vecTaskInfo.Begin();
					iCount++;
					continue;
				}
			}
			else if (it->id == id)
			{
				m_vecTaskInfo.Erase(it);
				iCount++;
				break;
			}
			it++;
		}
		return iCount;
	}

	bool Toggle(bool bGet=false)
	{
		if (bGet)return m_bRunning;
		m_bRunning = !m_bRunning;
		return m_bRunning;
	}

protected:
	int ID_CYLRUNNER;
	T *m_pHandler;
	bool m_bStop;
	bool m_bRunning;
	kCores::Vector<TaskInfo*> m_vecTaskInfo;
	//std::queue<TaskInfo*> m_vecTaskInfo;

	int Runner(int arg0)
	{
		do
		{
			if (!m_bStop && !m_bRunning)
			{
#ifdef __WIN32__
				Sleep(50);
#elif defined __LINUX__
				usleep(50*1000);
#endif
				continue;
			}

			unsigned long tickNow = xUtils::SysUtil::GetCurrentTick();
			for (typename kCores::Vector<TaskInfo*>::Iterator it = m_vecTaskInfo.Begin(); it != m_vecTaskInfo.End();it++)
			{
				if (it->trigTick < tickNow)
				{
					(m_pHandler->*it->pfnProc)(it->id, it->arg0, it->arg1, it->arg2);
					delete m_vecTaskInfo.Erase(it);
					break;
				}
			}

			//delete pTaskInfo;
		} while (!m_bStop); // 经测试,continue可以执行到此条件

		return 0;
	}
};


	template<class T>
	class MsgQue : public virtual Final<MsgQue<T> > // linux error: '>>' should be '> >' within a nested template argument list
	{
	public:
		struct QMSG
		{
		public:
			QMSG()
			{
				memset(this, 0, sizeof(QMSG));
			}
			QMSG(QMSG &qMsg)
			{
				if (this!=&qMsg) *this = qMsg;
			}
			QMSG(int i4, char *str4k, void *wp, void *lp) :QMSG()
			{
				this->i4 = i4;
				if (str4k)strcpy(this->str4k, str4k);
				this->wp = wp;
				this->lp = lp;
			}
			QMSG & operator=(const QMSG &qMsg)
			{
				this->i4 = qMsg.i4;
				if (qMsg.str4k)strcpy(this->str4k, qMsg.str4k);
				this->wp = qMsg.wp;
				this->lp = qMsg.lp;
				return *this;
			}
			int i4;
			char str4k[4096];
			void *wp;
			void *lp;
		};

		inline MsgQue(int nSize)
		{
			m_nSize = nSize;
			m_nCount = 0;

			m_pNodes = NULL;
			m_pFlags = NULL;

			m_nHeadIndex = 0;
			m_nTailIndex = 0;

			m_pNodes = new QMSG[m_nSize];
			memset(m_pNodes, 0, m_nSize * sizeof(QMSG));

			m_pFlags = new unsigned int[m_nSize];
			memset(m_pFlags, 0, m_nSize * sizeof(int));
		}

		inline ~MsgQue()
		{
			delete[] m_pNodes;
			delete[] m_pFlags;
		}

		inline unsigned int GetCount(){ return m_nCount; }

		//inline bool Send(QMSG msg)
		//{
		//	return 0;
		//}

		// 第4个参数设计为指针而非对象或引用,是为了可以传默认NULL值
		inline bool Post(int i4, char *str4k = NULL, void *wp = NULL, void *lp = NULL)
		{
			if (!m_mxPush.Lock())
			{
				return false;
			}
			unsigned int  nCur_index = m_nTailIndex;
			unsigned int* nCur_flag = m_pFlags + nCur_index;

#if defined(WIN32) || defined(WIN64)
			unsigned int nOldValue = InterlockedCompareExchange(nCur_flag, 1, 0);
#else
			unsigned int nOldValue = __sync_val_compare_and_swap(nCur_flag, 0, 1);
#endif
			if (nOldValue == 0) //节点占用成功
			{
				m_nTailIndex++;
				if (m_nTailIndex == m_nSize)
				{
					m_nTailIndex = 0;
				}
				m_mxPush.UnLock();
			}
			else         //节点已被占用(队列已满)
			{
				m_mxPush.UnLock();
				return false;
			}

#if defined(WIN32) || defined(WIN64)
			InterlockedIncrement(&m_nCount);   //个数递增
#else
			__sync_fetch_and_add(&m_nCount, 1);
#endif
			*(m_pNodes + nCur_index) = QMSG(i4, str4k, wp, lp);  //写入节点

#if defined(WIN32) || defined(WIN64)
			InterlockedIncrement(nCur_flag);   //写入完毕
#else
			__sync_fetch_and_add(nCur_flag, 1);
#endif
			m_Signal.Notify();
			return true;
		}

		bool PopFront(QMSG *pMsg)
		{
			if (!m_mxPop.Lock())
			{
				return FALSE;
			}
			unsigned int  nCur_index = m_nHeadIndex;
			unsigned int* nCur_flag = m_pFlags + nCur_index;

#if defined(WIN32) || defined(WIN64)
			unsigned int nOldValue = InterlockedCompareExchange(nCur_flag, 3, 2);
#else
			unsigned int nOldValue = __sync_val_compare_and_swap(nCur_flag, 2, 3);
#endif
			if (nOldValue == 2) //节点占用成功
			{
				m_nHeadIndex++;
				if (m_nHeadIndex == m_nSize)
				{
					m_nHeadIndex = 0;
				}
				m_mxPop.UnLock();
			}
			else        //节点为空(队列为空)
			{
				m_mxPop.UnLock();
				m_Signal.Wait();
				return PopFront(pMsg);
			}

#if defined(WIN32) || defined(WIN64)
			InterlockedDecrement(&m_nCount);    //个数递减
#else
			__sync_fetch_and_sub(&m_nCount, 1);
#endif

			*pMsg = *(m_pNodes + nCur_index);   //取出节点

#if defined(WIN32) || defined(WIN64)
			InterlockedExchangeSubtract(nCur_flag, 3); //取出完毕
#else
			__sync_fetch_and_sub(nCur_flag, 3);
#endif
			return true;
		}

		template<typename i_i_s_p>
		int Loop(i_i_s_p pfnMsgLoop, T *pThis)
		{
			QMSG msg;
			while (PopFront(&msg))
			{
				(pThis->*pfnMsgLoop)(msg.i4, msg.str4k, msg.wp, msg.lp);
			}
			return 0;
		}

	public:
		Mutex m_mxPush;
		Mutex m_mxPop;
		Signal m_Signal;

		inline bool Lock(unsigned int* pnlock);
		inline void UnLock(unsigned int* pnlock);

		unsigned int      m_nSize;        //环形队列的大小;
		unsigned int      m_nCount;       //队列中的个数

		QMSG*				m_pNodes;      //元素;
		unsigned int*     m_pFlags;       //标记某个位置的元素状态; 0:空节点; 1: 已被申请,正在写入; 2: 已经写入,可以弹出; 3: 正在弹出操作;

		unsigned int      m_nHeadIndex;   //队列最前面元素的位置;
		unsigned int      m_nTailIndex;   //队列最后面元素的位置;
	};

}

#endif

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xktesla

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值