⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 thread.h

📁 这是本人在工作中积累的VC++类库
💻 H
字号:
/************************************************************************
模快名:		moxu 公共类库
功能:		创建新线程
完成日期:	2007-10-20
作者:		许 培 Xu Pei(Email/MSN: peimoxu@163.com)

本代码可以自由使用,但因使用本代码造成的后果,本人不承担任何责任
************************************************************************/

#pragma once


#include <Windows.h>
#include <process.h>
#include "semaphore.h"
#include "Exception.h"

namespace moxu
{

	namespace detail
	{

		//////////////////////////////////////////////////////////////////////////
		//	for ThreadStart

		typedef char YES_TYPE;
		typedef int  NO_TYPE;

		YES_TYPE FunPtrTest( void(__cdecl*)() );
		YES_TYPE FunPtrTest( void(__stdcall*)() );
		YES_TYPE FunPtrTest( void(__fastcall*)() );
		NO_TYPE FunPtrTest(...);

		//////////////////////////////////////////////////////////////////////////

		struct SelectFirstType
		{
			template<class A, class B>
			struct Template { typedef A Type; };
		};

		struct SelectSecondType
		{
			template<class A, class B>
			struct Template { typedef B Type; };
		};

		template<bool condition>
		struct SlectSelector
		{
			typedef SelectFirstType Type;
		};

		template <>
		struct SlectSelector<false>
		{
			typedef SelectSecondType Type;
		};


		template<bool Condition, typename A, typename B>
		struct SelectIf
		{
			typedef typename SlectSelector<Condition>::Type Selector;
			typedef typename Selector::template Template<A, B>::Type Type;
		};

		//////////////////////////////////////////////////////////////////////////

		template<bool a>
		struct FunPtrSelect
		{
			static const bool Value = true;
		};
		template<>
		struct FunPtrSelect<false>
		{
			static const bool Value = false;
		};

		template<typename T>
		struct IsFunPtr
		{
			static T& MakeT();
			static const bool Value = FunPtrSelect<(1 == sizeof(FunPtrTest(MakeT())))>::Value;
		};

		//////////////////////////////////////////////////////////////////////////

		struct FunPtrTag{};
		struct ObjPtrTag{};

		template<typename T>
		struct GetFunType
		{
			typedef typename SelectIf<IsFunPtr<T>::Value, FunPtrTag, ObjPtrTag>::Type Type;
		};

		union FunctionPtrType
		{
			void(*FunPtr)();
			void* ObjPtr;
		};

		template<typename T>
		void FunInvoker(FunctionPtrType funType)
		{
			T fun = funType.FunPtr;
			fun();
		}

		template<typename T>
		void ObjInvoker(FunctionPtrType funType)
		{
			T* pFun = (T*)(funType.ObjPtr);
			(*pFun)();
		}

		template<typename T>
		FunctionPtrType FunPtrCopy(FunctionPtrType funType)
		{
			return funType;
		}

		template<typename T>
		FunctionPtrType ObjPtrCopy(FunctionPtrType funType)
		{
			FunctionPtrType temp;
			temp.ObjPtr = (void*)new T(*((T*)funType.ObjPtr));
			return temp;
		}

		template<typename T>
		void DeleteFunObj(FunctionPtrType obj)
		{
			T* p = (T*)obj.ObjPtr;
			delete p;
		}

		//////////////////////////////////////////////////////////////////////////
		//	function

		class ThreadStart
		{
		protected:
			typedef void(*InvokerType)(FunctionPtrType);
			typedef void(*DeleteObj)(FunctionPtrType);
			typedef FunctionPtrType(*CopyFunPtr)(FunctionPtrType);
			InvokerType m_invoker;
			DeleteObj m_delObj;
			CopyFunPtr m_copyFunPtr;
			FunctionPtrType m_funPtr;
			bool m_isObj;

		public:
			template<typename Functor>
			ThreadStart(Functor fun)
			{
				typedef typename GetFunType<Functor>::Type tag;
				Init(fun, tag());
			}

			ThreadStart(const ThreadStart& other)
			{
				m_invoker = other.m_invoker;
				m_delObj = other.m_delObj;
				m_isObj = other.m_isObj;
				m_copyFunPtr = other.m_copyFunPtr;
				m_funPtr = other.m_copyFunPtr(other.m_funPtr);
			}

			ThreadStart& operator=(const ThreadStart& other)
			{
				m_invoker = other.m_invoker;
				m_delObj = other.m_delObj;
				m_isObj = other.m_isObj;
				m_copyFunPtr = other.m_copyFunPtr;
				m_funPtr = other.m_copyFunPtr(other.m_funPtr);
				return *this;
			}

			virtual ~ThreadStart(void)
			{
				if(m_isObj)
					m_delObj(m_funPtr);
			}

		public:
			void operator()()
			{
				m_invoker(m_funPtr);
			}

		protected:
			template<typename Functor>
			void Init(Functor fun, FunPtrTag)
			{
				m_funPtr.FunPtr = fun;
				m_invoker = FunInvoker<Functor>;
				m_copyFunPtr = FunPtrCopy<Functor>;
				m_isObj = false;
			}

			template<typename Functor>
			void Init(Functor& fun, ObjPtrTag)
			{
				m_funPtr.ObjPtr = (void*)new Functor(fun);
				m_invoker = ObjInvoker<Functor>;
				m_delObj = DeleteFunObj<Functor>;
				m_copyFunPtr = ObjPtrCopy<Functor>;
				m_isObj = true;
			}
		};

		//////////////////////////////////////////////////////////////////////////
		// for Thread

		class ThreadParam
		{
		private:
			ThreadStart m_start;
			Semaphore m_semaphore;

		public:
			ThreadParam(const ThreadStart& start) : m_start(start)
			{
				if(!m_semaphore.Create(0, 1))
					throw Exception(_T("create semaphore error"));
			}
			
			~ThreadParam()
			{
				if(!m_semaphore.Close())
					throw Exception(_T("Close semaphor handle error"));
			}

			void Started()
			{
				if(!m_semaphore.Release())
					throw Exception(_T("Release semaphor error"));
			}

			void Wait()
			{
				if(!m_semaphore.Wait())
					throw Exception(_T("Wait for semaphor object error"));
			}

			ThreadStart& GetStart(){ return m_start; }
		};

		//////////////////////////////////////////////////////////////////////////
		// for Bind()

		template<typename C, typename F>
		class Binder
		{
		private:
			C m_class;
			F m_fun;

		public:
			Binder(C c, F f) : m_class(c), m_fun(f){ }
			void operator()()
			{
				(m_class->*m_fun)();
			}
		};

	}//namespace detail


	//////////////////////////////////////////////////////////////////////////
	//	convert void (classObj::*fun)(void) to a functor object

	template<typename C, typename F>
	detail::Binder<C, F> Bind(C c, F f)
	{
		return detail::Binder<C, F>(c, f);
	}

	//////////////////////////////////////////////////////////////////////////

	class Thread
	{
	private:
		unsigned int m_id;
		HANDLE m_handle;

	public:
		Thread() : m_handle(NULL), m_id(0) { }
		~Thread()
		{ 
			if(m_handle)
				CloseHandle(m_handle);
		}

		bool Start(const detail::ThreadStart& start);
		bool Join();
		DWORD GetId(){ return m_id; }

	private:
		static unsigned int WINAPI ThreadEntry(LPVOID lParam);
	};

}//namespace moxu

/*
using namespace moxu;

void TestFun()
{
	cout<<"Hello"<<endl;
}

class Test
{
public:
	void Disp()
	{
		cout<<"hi"<<endl;
	}

};

int main()
{
	Thread t1, t2;
	t1.Start(TestFun);
	t1.Join();

	Test test;
	t2.Start(Bind(&test, Test::Disp));
	t2.Join();
	return 0;
}

*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -