一个人的战争(2) : 成员函数与线程
2006-09-06 18:03
295 查看
本来今天打算贴BT Client的Tracker Requester的代码的,可是整理的不太完善,因为里面牵扯到很多线程和IOCP的东西,所以我先把一部分自己封装的线程代码贴上来供各位读者评论
先看下我对Win32线程的最浅封装,
注意这个是声明在thrad/win32/data_type.h下的
struct ThreadHandle //这个控制线程的句柄,ID等,提供这么各类主要是为了跨平台的考虑(并不成熟)
...{
HANDLE m_hdl;
t_u_int32 m_tid;
bool m_is_suspend;
};
struct ThreadAttr //属性类
...{
t_u_int32 stack_size;
t_u_int32 priority;
t_u_int32 create_flags;
public:
ThreadAttr() : stack_size(0), priority(0), create_flags(0) ...{ }
};
typedef unsigned int (__stdcall *ThreadFun)(void *); //win32下的被调用的函数原型
下面这部分用了点Bridge模式,有点繁杂,不过是为了一个不成熟的跨平台考虑的
/**//****************************************************threadx_impl_base.h*******************************************/
#include "thread_def.h"
#include "../misc/non_copy_able.h"
namespace ThreadSpace ...{
enum ThreadPriority ...{ HIGH, NORMAL, LOW }; //优先级控制
struct ThreadImpl : private NonCopyable //各个平台要提供的线程控制的Impl_基类
...{
virtual ThreadHandle* get_handle() = 0;
virtual void terminate() = 0;
virtual bool suspend() = 0;
virtual bool resume() = 0;
virtual ThreadPriority get_priority() const = 0;
virtual bool set_priority(ThreadPriority tp) = 0;
virtual bool is_active() const = 0;
//virtual t_u_long wait_for_end(t_u_long timeout) = 0;
virtual ~ThreadImpl()...{ };
};
}
/**//*****************************************************threadx.h*****************************************************************/
#include "thread_def.h"
#include "threadx_impl_base.h"
namespace ThreadSpace ...{
class ThreadX : private NonCopyable
...{
private:
ThreadImpl *m_pimpl;
public:
ThreadHandle* get_handle();
void terminate();
ThreadX(ThreadImpl *pimpl);
bool suspend();
bool resume();
ThreadPriority get_priority() const;
bool set_priority(ThreadPriority tp);
bool is_active() const;
//t_u_long wait_for_end(t_u_long timeout = INFINITE);
virtual ~ThreadX();
};
}
/**//**********************************************************threadx.cpp*********************************************************************/
#include "threadx.h"
namespace ThreadSpace ...{
ThreadX::ThreadX(ThreadImpl *pimpl) : m_pimpl(pimpl) ...{ }
bool ThreadX::suspend()
...{
return m_pimpl->suspend();
}
bool ThreadX::resume()
...{
return m_pimpl->resume();
}
void ThreadX::terminate()
...{
m_pimpl->terminate();
}
ThreadPriority ThreadX::get_priority() const
...{
return m_pimpl->get_priority();
}
bool ThreadX::set_priority(ThreadPriority tp)
...{
return m_pimpl->set_priority(tp);
}
ThreadX::~ThreadX() ...{ delete m_pimpl; }
bool ThreadX::is_active() const
...{
return m_pimpl->is_active();
}
ThreadHandle* ThreadX::get_handle()
...{
return m_pimpl->get_handle();
}
}
/**//*******************************************************threadx_impl.h(在win32/)********************************************************/
#pragma once
#include "../threadx_impl_base.h"
#include "../thread_expt.h"
namespace ThreadSpace ...{
class Win32ThreadImpl : public ThreadImpl
...{
private:
ThreadHandle m_handle;
public:
Win32ThreadImpl(HANDLE hdl, t_u_long tid, bool is_suspend);
virtual ~Win32ThreadImpl();
public:
virtual ThreadHandle* get_handle();
virtual void terminate();
virtual bool suspend();
virtual bool resume();
virtual ThreadPriority get_priority() const;
virtual bool set_priority(ThreadPriority tp);
virtual bool is_active()const;
//virtual t_u_long wait_for_end(t_u_long timeout);
};
}
/**//************************************************************threadx_impl.cpp(win32/)*****************************************************/
#include "threadx_impl.h"
namespace ThreadSpace ...{
Win32ThreadImpl::Win32ThreadImpl(HANDLE hdl, t_u_long tid, bool is_suspend) //: m_hdl(hdl),
m_tid(tid),
m_is_suspend(is_suspend)
...{
m_handle.m_hdl = hdl;
m_handle.m_tid = tid;
m_handle.m_is_suspend = is_suspend;
}
Win32ThreadImpl::~Win32ThreadImpl()
...{
::CloseHandle(m_handle.m_hdl);
}
bool Win32ThreadImpl::is_active()const
...{
t_u_long code;
if(::GetExitCodeThread(m_handle.m_hdl, &code) == 0) throw ThreadExpt(::GetLastError());
return (code == STILL_ACTIVE);
}
void Win32ThreadImpl::terminate()
...{
::TerminateThread(m_handle.m_hdl, -1);
}
bool Win32ThreadImpl::suspend()
...{
if(m_handle.m_is_suspend) return true;
if(::SuspendThread(m_handle.m_hdl) == -1)...{
return false;
}else ...{
m_handle.m_is_suspend = true;
return true;
}
}
bool Win32ThreadImpl::resume()
...{
if(!m_handle.m_is_suspend) return true;
if(::ResumeThread(m_handle.m_hdl) == -1)...{
return false;
}else...{
m_handle.m_is_suspend = false;
return true;
}
}
ThreadPriority Win32ThreadImpl::get_priority() const
...{
int res = ::GetThreadPriority(m_handle.m_hdl);
if(res == THREAD_PRIORITY_ERROR_RETURN) throw ThreadExpt(::GetLastError());
switch(res)...{
case THREAD_PRIORITY_TIME_CRITICAL:
case THREAD_PRIORITY_HIGHEST:
return HIGH;
case THREAD_PRIORITY_ABOVE_NORMAL:
case THREAD_PRIORITY_NORMAL:
case THREAD_PRIORITY_BELOW_NORMAL:
return NORMAL;
default:
return LOW; //case THREAD_PRIORITY_LOWEST:
//case THREAD_PRIORITY_IDLE:
}
}
bool Win32ThreadImpl::set_priority(ThreadPriority tp)
...{
switch(tp)...{
case HIGH:
return (::SetThreadPriority(m_handle.m_hdl, THREAD_PRIORITY_HIGHEST) != 0);
case LOW:
return (::SetThreadPriority(m_handle.m_hdl, THREAD_PRIORITY_LOWEST) != 0);
default:
return (::SetThreadPriority(m_handle.m_hdl, THREAD_PRIORITY_NORMAL) != 0);
}
}
/**//*t_u_long Win32ThreadImpl::wait_for_end(t_u_long timeout)
{
return ::WaitForSingleObject(m_handle.m_hdl, timeout);
}*/
ThreadHandle* Win32ThreadImpl::get_handle()
...{
return &m_handle;
}
}
以上是大概齐的框架,下面请看如何启动一个线程
/**//***************************************************************aux_fun.h*******************************************************/
#pragma once
#include "thread_def.h"
namespace ThreadSpace ...{
class ThreadX;
ThreadX* create_thread(ThreadFun proc, void *param, const ThreadAttr &attr); //创建一个线程(在各文件夹下有不同的实现)
void free_thread(ThreadX *&pthread);//delete ThreadX*... 同上
t_u_long wait_thread(ThreadX *pthread, t_u_long timeout = INFINITE); //等待一个线程结束
t_u_long wait_multi_thread(ThreadX **ppthread, size_t count, bool wait_all = true, t_u_long timeout ); 等待所有一组结束
}
/**//**************************************************axu_fun.cpp (win32/)************************************************/
#include "../aux_fun.h"
#include "../threadx.h"
#include "threadx_impl.h"
#include <vector>
#include <cassert>
namespace ThreadSpace ...{
ThreadX* create_thread(ThreadFun proc, void *param, const ThreadAttr &attr)
...{
t_u_int32 tid;
HANDLE hdl = (HANDLE)_beginthreadex(0, attr.stack_size, proc, param, attr.create_flags, &tid);
if(hdl == 0) throw(ThreadExpt(errno));
return new ThreadX(new Win32ThreadImpl(hdl, tid, (attr.create_flags == CREATE_SUSPENDED)));
}
void free_thread(ThreadX *&pthread)
...{
assert(pthread != 0);
try...{
delete pthread;
pthread = 0;
}catch(...)
...{
}
}
t_u_long wait_thread(ThreadX *pthread, t_u_long timeout)
...{
assert(pthread != 0);
t_u_long res = ::WaitForSingleObject(pthread->get_handle()->m_hdl, timeout);
if(res == WAIT_FAILED) throw (ThreadExpt(::GetLastError()));
return res;
}
t_u_long wait_multi_thread(ThreadX **ppthread, size_t count, bool wait_all, t_u_long timeout)
...{
assert(ppthread != 0);
std::vector<HANDLE> vhdl;
for(size_t i = 0; i < count; ++i)
vhdl.push_back(ppthread[i]->get_handle()->m_hdl);
t_u_long res = ::WaitForMultipleObjects(count, &vhdl[0], wait_all, timeout);
if(res == WAIT_FAILED) throw(ThreadExpt(::GetLastError()));
return res;
}
恩,下面是关键了,就是我们如何直接把一成员函数当做线程来执行平是我们的习惯是
class Test
...{
public:
void test() ...{ printf("xxxxxxxxx"); } //成员函数
static unsigned int WINAPI ThreadFun(void *pvoid)
...{
Test *ptest = static_cast<Test*>(pvoid);
ptest->test();
return 0;
}
};
int main()
...{
Test test;
HANDLE hdl = (HANDLE)_beginthreadex(0, 0, Test::ThreadFun, (void*)&test, 0, 0);
cin.get();
return 0;
}
如果我们希望直接启动这个成员函数呢?OK,下面有些复杂的模板定义,请注意,这些东西也许无意义,但很有意思
#pragma once
#include <memory>
namespace ThreadSpace ...{
template<class T, class MF, class P>
struct ThreadInfo
...{
T *ptype; //传递进来的那个类的指针;
MF mem_fun; //类成员函数指针
P *param; //参数指针;
ThreadInfo(T *pt, MF mf, P *pa) : ptype(pt), mem_fun(mf), param(pa) ...{ }
};
template<class ExecImpl>
class MemFunExector
...{
private:
typedef typename ExecImpl::HandleType HandleType; //见下面的ExecImpBase注释
typedef typename ExecImpl::Result Result;
typedef typename ExecImpl::Param Param;
private:
template<class C>//这个是那个被执行的线程函数,根据被实例化的不同的ThreadInfo模板来作实例化
static Result ThreadFunc(Param param)
...{
std::auto_ptr<C> p_info((C*)param);
//这样,根据调用一个函数指针来调用相应的成员函数
return ((p_info->ptype)->*(p_info->mem_fun))(*p_info->param);
}
public://首先这个模板函数接受一个类的指针,这个类的成员函数指针和成员函数参数
template<class Type, class MFun, class MParam>
HandleType operator()(Type *pt, MFun fun, MParam ¶m)
...{
//ThreadInfo<Type, MFun, MParam>相应的ThreadInfo实例化,这个类同样作为记录参数信息来用的
//ThreadFunc再根据上面的ThradInfo类作实例化
return ExecImpl()(ThreadFunc<ThreadInfo<Type, MFun, MParam> >, (Param)(new ThreadInfo<Type, MFun, MParam>(pt, fun, ¶m)));
}
template<class Type, class MFun, class MParam, class ATTR>
HandleType operator()(Type *pt, MFun fun, MParam ¶m, ATTR &attr)
...{
return ExecImpl(attr)(ThreadFunc<ThreadInfo<Type, MFun, MParam> >, (Param)(new ThreadInfo<Type, MFun, MParam>(pt, fun, ¶m)));
}
};
//这个类是为了提供不同平台的线程启动函数兼容的,每个平台都应该有一个不同的派生类
template<class H, class R, class P>
struct ExecImpBase
...{
typedef H HandleType; //注意,这个是启动那个成员函数返回的句柄,例如ThreadX*
typedef R Result; //这个是那个成员函数的返回值,类似unsigned int
typedef P Param; //那个成员函数的参数,类似void*p等,以后定义
typedef Result (*PF)(Param);
virtual HandleType operator()(PF pf, Param param) = 0;
};
}
根据平台定义相应的Traits类
#pragma once
#include "../mem_fun_exector.h"
namespace ThreadSpace ...{
class ThreadX;
struct ThreadAttr;
struct ExecutorWin32 : public ExecImpBase<ThreadX*, unsigned int, void*>
...{
const ThreadAttr &m_attr;
ExecutorWin32(const ThreadAttr &attr);
virtual HandleType operator()(PF pf, Param param);
};
#define MFExecutor(type, mfun, param, attr)
MemFunExector<ExecutorWin32>()((type), (mfun), (param), (attr))
}
class Test
...{
public:
void test(void *p) ...{ printf("xxxxxxxxx"); } //成员函数 注意,这个和上个不同,加了个void*p作为参数,是为了兼容那个模板
};
int main()
...{
Test test;
ThreadAttr attr;
void *p = 0;
MFExecutor(&test, Test::test, p, attr);
cin.get();
return 0;
}
OK,这部分就到此为止了,有什么错误请各位读者指教,有喜欢模板的朋友请加我QQ 2070341,明天我会贴IOCP的相关类或者Tracker requester类的代码,请各位看官支持,谢谢
先看下我对Win32线程的最浅封装,
注意这个是声明在thrad/win32/data_type.h下的
struct ThreadHandle //这个控制线程的句柄,ID等,提供这么各类主要是为了跨平台的考虑(并不成熟)
...{
HANDLE m_hdl;
t_u_int32 m_tid;
bool m_is_suspend;
};
struct ThreadAttr //属性类
...{
t_u_int32 stack_size;
t_u_int32 priority;
t_u_int32 create_flags;
public:
ThreadAttr() : stack_size(0), priority(0), create_flags(0) ...{ }
};
typedef unsigned int (__stdcall *ThreadFun)(void *); //win32下的被调用的函数原型
下面这部分用了点Bridge模式,有点繁杂,不过是为了一个不成熟的跨平台考虑的
/**//****************************************************threadx_impl_base.h*******************************************/
#include "thread_def.h"
#include "../misc/non_copy_able.h"
namespace ThreadSpace ...{
enum ThreadPriority ...{ HIGH, NORMAL, LOW }; //优先级控制
struct ThreadImpl : private NonCopyable //各个平台要提供的线程控制的Impl_基类
...{
virtual ThreadHandle* get_handle() = 0;
virtual void terminate() = 0;
virtual bool suspend() = 0;
virtual bool resume() = 0;
virtual ThreadPriority get_priority() const = 0;
virtual bool set_priority(ThreadPriority tp) = 0;
virtual bool is_active() const = 0;
//virtual t_u_long wait_for_end(t_u_long timeout) = 0;
virtual ~ThreadImpl()...{ };
};
}
/**//*****************************************************threadx.h*****************************************************************/
#include "thread_def.h"
#include "threadx_impl_base.h"
namespace ThreadSpace ...{
class ThreadX : private NonCopyable
...{
private:
ThreadImpl *m_pimpl;
public:
ThreadHandle* get_handle();
void terminate();
ThreadX(ThreadImpl *pimpl);
bool suspend();
bool resume();
ThreadPriority get_priority() const;
bool set_priority(ThreadPriority tp);
bool is_active() const;
//t_u_long wait_for_end(t_u_long timeout = INFINITE);
virtual ~ThreadX();
};
}
/**//**********************************************************threadx.cpp*********************************************************************/
#include "threadx.h"
namespace ThreadSpace ...{
ThreadX::ThreadX(ThreadImpl *pimpl) : m_pimpl(pimpl) ...{ }
bool ThreadX::suspend()
...{
return m_pimpl->suspend();
}
bool ThreadX::resume()
...{
return m_pimpl->resume();
}
void ThreadX::terminate()
...{
m_pimpl->terminate();
}
ThreadPriority ThreadX::get_priority() const
...{
return m_pimpl->get_priority();
}
bool ThreadX::set_priority(ThreadPriority tp)
...{
return m_pimpl->set_priority(tp);
}
ThreadX::~ThreadX() ...{ delete m_pimpl; }
bool ThreadX::is_active() const
...{
return m_pimpl->is_active();
}
ThreadHandle* ThreadX::get_handle()
...{
return m_pimpl->get_handle();
}
}
/**//*******************************************************threadx_impl.h(在win32/)********************************************************/
#pragma once
#include "../threadx_impl_base.h"
#include "../thread_expt.h"
namespace ThreadSpace ...{
class Win32ThreadImpl : public ThreadImpl
...{
private:
ThreadHandle m_handle;
public:
Win32ThreadImpl(HANDLE hdl, t_u_long tid, bool is_suspend);
virtual ~Win32ThreadImpl();
public:
virtual ThreadHandle* get_handle();
virtual void terminate();
virtual bool suspend();
virtual bool resume();
virtual ThreadPriority get_priority() const;
virtual bool set_priority(ThreadPriority tp);
virtual bool is_active()const;
//virtual t_u_long wait_for_end(t_u_long timeout);
};
}
/**//************************************************************threadx_impl.cpp(win32/)*****************************************************/
#include "threadx_impl.h"
namespace ThreadSpace ...{
Win32ThreadImpl::Win32ThreadImpl(HANDLE hdl, t_u_long tid, bool is_suspend) //: m_hdl(hdl),
m_tid(tid),
m_is_suspend(is_suspend)
...{
m_handle.m_hdl = hdl;
m_handle.m_tid = tid;
m_handle.m_is_suspend = is_suspend;
}
Win32ThreadImpl::~Win32ThreadImpl()
...{
::CloseHandle(m_handle.m_hdl);
}
bool Win32ThreadImpl::is_active()const
...{
t_u_long code;
if(::GetExitCodeThread(m_handle.m_hdl, &code) == 0) throw ThreadExpt(::GetLastError());
return (code == STILL_ACTIVE);
}
void Win32ThreadImpl::terminate()
...{
::TerminateThread(m_handle.m_hdl, -1);
}
bool Win32ThreadImpl::suspend()
...{
if(m_handle.m_is_suspend) return true;
if(::SuspendThread(m_handle.m_hdl) == -1)...{
return false;
}else ...{
m_handle.m_is_suspend = true;
return true;
}
}
bool Win32ThreadImpl::resume()
...{
if(!m_handle.m_is_suspend) return true;
if(::ResumeThread(m_handle.m_hdl) == -1)...{
return false;
}else...{
m_handle.m_is_suspend = false;
return true;
}
}
ThreadPriority Win32ThreadImpl::get_priority() const
...{
int res = ::GetThreadPriority(m_handle.m_hdl);
if(res == THREAD_PRIORITY_ERROR_RETURN) throw ThreadExpt(::GetLastError());
switch(res)...{
case THREAD_PRIORITY_TIME_CRITICAL:
case THREAD_PRIORITY_HIGHEST:
return HIGH;
case THREAD_PRIORITY_ABOVE_NORMAL:
case THREAD_PRIORITY_NORMAL:
case THREAD_PRIORITY_BELOW_NORMAL:
return NORMAL;
default:
return LOW; //case THREAD_PRIORITY_LOWEST:
//case THREAD_PRIORITY_IDLE:
}
}
bool Win32ThreadImpl::set_priority(ThreadPriority tp)
...{
switch(tp)...{
case HIGH:
return (::SetThreadPriority(m_handle.m_hdl, THREAD_PRIORITY_HIGHEST) != 0);
case LOW:
return (::SetThreadPriority(m_handle.m_hdl, THREAD_PRIORITY_LOWEST) != 0);
default:
return (::SetThreadPriority(m_handle.m_hdl, THREAD_PRIORITY_NORMAL) != 0);
}
}
/**//*t_u_long Win32ThreadImpl::wait_for_end(t_u_long timeout)
{
return ::WaitForSingleObject(m_handle.m_hdl, timeout);
}*/
ThreadHandle* Win32ThreadImpl::get_handle()
...{
return &m_handle;
}
}
以上是大概齐的框架,下面请看如何启动一个线程
/**//***************************************************************aux_fun.h*******************************************************/
#pragma once
#include "thread_def.h"
namespace ThreadSpace ...{
class ThreadX;
ThreadX* create_thread(ThreadFun proc, void *param, const ThreadAttr &attr); //创建一个线程(在各文件夹下有不同的实现)
void free_thread(ThreadX *&pthread);//delete ThreadX*... 同上
t_u_long wait_thread(ThreadX *pthread, t_u_long timeout = INFINITE); //等待一个线程结束
t_u_long wait_multi_thread(ThreadX **ppthread, size_t count, bool wait_all = true, t_u_long timeout ); 等待所有一组结束
}
/**//**************************************************axu_fun.cpp (win32/)************************************************/
#include "../aux_fun.h"
#include "../threadx.h"
#include "threadx_impl.h"
#include <vector>
#include <cassert>
namespace ThreadSpace ...{
ThreadX* create_thread(ThreadFun proc, void *param, const ThreadAttr &attr)
...{
t_u_int32 tid;
HANDLE hdl = (HANDLE)_beginthreadex(0, attr.stack_size, proc, param, attr.create_flags, &tid);
if(hdl == 0) throw(ThreadExpt(errno));
return new ThreadX(new Win32ThreadImpl(hdl, tid, (attr.create_flags == CREATE_SUSPENDED)));
}
void free_thread(ThreadX *&pthread)
...{
assert(pthread != 0);
try...{
delete pthread;
pthread = 0;
}catch(...)
...{
}
}
t_u_long wait_thread(ThreadX *pthread, t_u_long timeout)
...{
assert(pthread != 0);
t_u_long res = ::WaitForSingleObject(pthread->get_handle()->m_hdl, timeout);
if(res == WAIT_FAILED) throw (ThreadExpt(::GetLastError()));
return res;
}
t_u_long wait_multi_thread(ThreadX **ppthread, size_t count, bool wait_all, t_u_long timeout)
...{
assert(ppthread != 0);
std::vector<HANDLE> vhdl;
for(size_t i = 0; i < count; ++i)
vhdl.push_back(ppthread[i]->get_handle()->m_hdl);
t_u_long res = ::WaitForMultipleObjects(count, &vhdl[0], wait_all, timeout);
if(res == WAIT_FAILED) throw(ThreadExpt(::GetLastError()));
return res;
}
恩,下面是关键了,就是我们如何直接把一成员函数当做线程来执行平是我们的习惯是
class Test
...{
public:
void test() ...{ printf("xxxxxxxxx"); } //成员函数
static unsigned int WINAPI ThreadFun(void *pvoid)
...{
Test *ptest = static_cast<Test*>(pvoid);
ptest->test();
return 0;
}
};
int main()
...{
Test test;
HANDLE hdl = (HANDLE)_beginthreadex(0, 0, Test::ThreadFun, (void*)&test, 0, 0);
cin.get();
return 0;
}
如果我们希望直接启动这个成员函数呢?OK,下面有些复杂的模板定义,请注意,这些东西也许无意义,但很有意思
#pragma once
#include <memory>
namespace ThreadSpace ...{
template<class T, class MF, class P>
struct ThreadInfo
...{
T *ptype; //传递进来的那个类的指针;
MF mem_fun; //类成员函数指针
P *param; //参数指针;
ThreadInfo(T *pt, MF mf, P *pa) : ptype(pt), mem_fun(mf), param(pa) ...{ }
};
template<class ExecImpl>
class MemFunExector
...{
private:
typedef typename ExecImpl::HandleType HandleType; //见下面的ExecImpBase注释
typedef typename ExecImpl::Result Result;
typedef typename ExecImpl::Param Param;
private:
template<class C>//这个是那个被执行的线程函数,根据被实例化的不同的ThreadInfo模板来作实例化
static Result ThreadFunc(Param param)
...{
std::auto_ptr<C> p_info((C*)param);
//这样,根据调用一个函数指针来调用相应的成员函数
return ((p_info->ptype)->*(p_info->mem_fun))(*p_info->param);
}
public://首先这个模板函数接受一个类的指针,这个类的成员函数指针和成员函数参数
template<class Type, class MFun, class MParam>
HandleType operator()(Type *pt, MFun fun, MParam ¶m)
...{
//ThreadInfo<Type, MFun, MParam>相应的ThreadInfo实例化,这个类同样作为记录参数信息来用的
//ThreadFunc再根据上面的ThradInfo类作实例化
return ExecImpl()(ThreadFunc<ThreadInfo<Type, MFun, MParam> >, (Param)(new ThreadInfo<Type, MFun, MParam>(pt, fun, ¶m)));
}
template<class Type, class MFun, class MParam, class ATTR>
HandleType operator()(Type *pt, MFun fun, MParam ¶m, ATTR &attr)
...{
return ExecImpl(attr)(ThreadFunc<ThreadInfo<Type, MFun, MParam> >, (Param)(new ThreadInfo<Type, MFun, MParam>(pt, fun, ¶m)));
}
};
//这个类是为了提供不同平台的线程启动函数兼容的,每个平台都应该有一个不同的派生类
template<class H, class R, class P>
struct ExecImpBase
...{
typedef H HandleType; //注意,这个是启动那个成员函数返回的句柄,例如ThreadX*
typedef R Result; //这个是那个成员函数的返回值,类似unsigned int
typedef P Param; //那个成员函数的参数,类似void*p等,以后定义
typedef Result (*PF)(Param);
virtual HandleType operator()(PF pf, Param param) = 0;
};
}
根据平台定义相应的Traits类
#pragma once
#include "../mem_fun_exector.h"
namespace ThreadSpace ...{
class ThreadX;
struct ThreadAttr;
struct ExecutorWin32 : public ExecImpBase<ThreadX*, unsigned int, void*>
...{
const ThreadAttr &m_attr;
ExecutorWin32(const ThreadAttr &attr);
virtual HandleType operator()(PF pf, Param param);
};
#define MFExecutor(type, mfun, param, attr)
MemFunExector<ExecutorWin32>()((type), (mfun), (param), (attr))
}
class Test
...{
public:
void test(void *p) ...{ printf("xxxxxxxxx"); } //成员函数 注意,这个和上个不同,加了个void*p作为参数,是为了兼容那个模板
};
int main()
...{
Test test;
ThreadAttr attr;
void *p = 0;
MFExecutor(&test, Test::test, p, attr);
cin.get();
return 0;
}
OK,这部分就到此为止了,有什么错误请各位读者指教,有喜欢模板的朋友请加我QQ 2070341,明天我会贴IOCP的相关类或者Tracker requester类的代码,请各位看官支持,谢谢
相关文章推荐
- 由一个成员函数来启动一个线程
- 在单独线程中执行对象成员函数
- 如何实现类成员函数创建线程
- 成员函数做为线程函数
- 怎样在线程中运行类的成员函数
- 如何实现利用类成员函数创建线程
- 如何实现利用类成员函数创建线程 选择自 iceezone 的 Blog
- 创建线程,让线程函数回调函数也像成员函数一样
- 类的成员函数做线程的创建
- 利用QT的QThread将一个类中的成员函数转到线程下执行
- 线程调用成员函数
- 将线程函数做成成员函数的方法
- C++中 线程函数为静态函数 及 类成员函数作为回调函数
- 类的非静态成员函数作为线程函数的注意事项
- 非静态成员函数作为线程入口
- 线程创建函数与类成员函数
- 不使用汇编在vc中转换类的成员函数为一个线程的通用代码
- 类成员函数创建线程
- 类的非静态成员函数作为线程函数
- 如何实现类的成员函数创建线程