📄 thread.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 + -