以下是一个线程类的实现:
#include <assert.h>
#include <process.h>
class thread
{
HANDLE m_th;
DWORD m_flags;
unsigned m_tid;
unsigned m_code;
unsigned m_stack;
DWORD m_priority;
enum{EXITTING=1,SELFDELETE=2,};
protected:
//return FALSE to exit thread work loop
virtual BOOL run()=0;
void cleanup()
{
if(m_th)
{
WaitForSingleObject(m_th,(unsigned long)-1);
CloseHandle(m_th);
m_th = 0;
}
}
void threadRoutine()
{
if(!m_cx ||!m_tp) return;
if(!m_tid) m_tid = GetCurrentThreadId();
if(m_priority!=0) adjustPriority(m_priority);
for(;!isExitting();)
{
try
{
if(!run()) break;
}
catch(...){break;}
}
}
static unsigned __stdcall stubRoutine(thread *t)
{
assert(t);
t->threadRoutine();
unsigned code = t->m_code;
if(t->isAutoDelete()) delete t;
_endthreadex(code);
return 0;
}
//no copy ctor
thread(const thread& s);
//no assignment
thread& operator=(const thread& s);
public:
thread() : m_th(0),m_flags(0),m_tid(0),m_code(0),m_stack(0),m_priority(0){}
~thread(){stop(INFINITE);}
unsigned getTid() const{return m_tid;}
HANDLE getHandle() const{return m_th;}
unsigned getStack() const{return m_stack;}
unsigned getExitCode() const{return m_code;}
DWORD getPriority() const{return m_priority;}
BOOL isRunning() const{return m_th!=0;}
BOOL isExitting() const{return m_flags & EXITTING;}
BOOL isAutoDelete() const{return m_flags & SELFDELETE;}
unsigned setExitCode(unsigned e){return (m_code=e);}
void setAutoDelete(BOOL autoDel)
{
if(autoDel) m_flags |= SELFDELETE;
else m_flags &= ~SELFDELETE;
}
void detach()
{
if(m_th){CloseHandle(m_th);m_th=0;}
m_flags |= EXITTING;
}
BOOL stop(unsigned wait=0)
{
m_flags |= EXITTING;
if(m_flags & MAINTHREAD) return FALSE;
return waitForExit(wait);
}
void attach()
{
cleanup();
m_flags &= ~EXITTING;
HANDLE h = GetCurrentProcess();
DuplicateHandle(h,GetCurrentThread(),h,&m_th,0,0,DUPLICATE_SAME_ACCESS);
m_tid = (unsigned)GetCurrentThreadId();
threadRoutine();
detach();
}
void adjustPriority(DWORD priority)
{
if(!m_th || m_priority==priority) return;
SetThreadPriority(m_th,m_priority=priority);
}
BOOL start(DWORD priority=0,unsigned stack=0)
{
if(m_th) cleanup();
if(stack==(unsigned)-1) stack = 0;
m_stack = stack;
m_priority = priority;
m_flags &= ~EXITTING;
typedef UINT (__stdcall *THREADPROC)(void *);
m_th = (HANDLE)_beginthreadex(0,m_stack,(THREADPROC)&thread::stubRoutine,this,0,&m_tid);
if(!m_th) return FALSE;
return TRUE;
}
void standby(unsigned msec,BOOL isGUIThread)
{
if(!isGUIThread)
{
if(m_th) WaitForSingleObject(m_th,msec)!=WAIT_OBJECT_0);
}
else
{
if(!m_th) return;
DWORD time = timeGetTime();
for(;timeGetTime()-time<msec;)
{
if(MsgWaitForMultipleObjects(1,&m_th,FALSE,msec,QS_ALLEVENTS)==WAIT_OBJECT_0) break;
}
}
}
BOOL waitForExit(unsigned timeout=INFINITE)
{
return standby(timeout,FALSE);
}
};
需要线程的地方就从它派生一个类,并实现run()方法.线程一般是运行在一个循环内,所以该类包含了一个循环.
struct worker : public thread
{
virtual BOOL run()
{
printf("in worker thread!/n");
return FALSE;
}
}
void main()
{
printf("in main thread!/n");
worker worker1;
worker1.start();
worker1.waitForExit();
}
这个线程类够简单了,就是每次使用的时候都需要派生一次,执行的函数总是自包含的,不时特别方便.下一篇给出一个改进的例子,使用外部的接口类来执行,而不需要从thread类派生.
#include <assert.h>
#include <process.h>
class thread
{
HANDLE m_th;
DWORD m_flags;
unsigned m_tid;
unsigned m_code;
unsigned m_stack;
DWORD m_priority;
enum{EXITTING=1,SELFDELETE=2,};
protected:
//return FALSE to exit thread work loop
virtual BOOL run()=0;
void cleanup()
{
if(m_th)
{
WaitForSingleObject(m_th,(unsigned long)-1);
CloseHandle(m_th);
m_th = 0;
}
}
void threadRoutine()
{
if(!m_cx ||!m_tp) return;
if(!m_tid) m_tid = GetCurrentThreadId();
if(m_priority!=0) adjustPriority(m_priority);
for(;!isExitting();)
{
try
{
if(!run()) break;
}
catch(...){break;}
}
}
static unsigned __stdcall stubRoutine(thread *t)
{
assert(t);
t->threadRoutine();
unsigned code = t->m_code;
if(t->isAutoDelete()) delete t;
_endthreadex(code);
return 0;
}
//no copy ctor
thread(const thread& s);
//no assignment
thread& operator=(const thread& s);
public:
thread() : m_th(0),m_flags(0),m_tid(0),m_code(0),m_stack(0),m_priority(0){}
~thread(){stop(INFINITE);}
unsigned getTid() const{return m_tid;}
HANDLE getHandle() const{return m_th;}
unsigned getStack() const{return m_stack;}
unsigned getExitCode() const{return m_code;}
DWORD getPriority() const{return m_priority;}
BOOL isRunning() const{return m_th!=0;}
BOOL isExitting() const{return m_flags & EXITTING;}
BOOL isAutoDelete() const{return m_flags & SELFDELETE;}
unsigned setExitCode(unsigned e){return (m_code=e);}
void setAutoDelete(BOOL autoDel)
{
if(autoDel) m_flags |= SELFDELETE;
else m_flags &= ~SELFDELETE;
}
void detach()
{
if(m_th){CloseHandle(m_th);m_th=0;}
m_flags |= EXITTING;
}
BOOL stop(unsigned wait=0)
{
m_flags |= EXITTING;
if(m_flags & MAINTHREAD) return FALSE;
return waitForExit(wait);
}
void attach()
{
cleanup();
m_flags &= ~EXITTING;
HANDLE h = GetCurrentProcess();
DuplicateHandle(h,GetCurrentThread(),h,&m_th,0,0,DUPLICATE_SAME_ACCESS);
m_tid = (unsigned)GetCurrentThreadId();
threadRoutine();
detach();
}
void adjustPriority(DWORD priority)
{
if(!m_th || m_priority==priority) return;
SetThreadPriority(m_th,m_priority=priority);
}
BOOL start(DWORD priority=0,unsigned stack=0)
{
if(m_th) cleanup();
if(stack==(unsigned)-1) stack = 0;
m_stack = stack;
m_priority = priority;
m_flags &= ~EXITTING;
typedef UINT (__stdcall *THREADPROC)(void *);
m_th = (HANDLE)_beginthreadex(0,m_stack,(THREADPROC)&thread::stubRoutine,this,0,&m_tid);
if(!m_th) return FALSE;
return TRUE;
}
void standby(unsigned msec,BOOL isGUIThread)
{
if(!isGUIThread)
{
if(m_th) WaitForSingleObject(m_th,msec)!=WAIT_OBJECT_0);
}
else
{
if(!m_th) return;
DWORD time = timeGetTime();
for(;timeGetTime()-time<msec;)
{
if(MsgWaitForMultipleObjects(1,&m_th,FALSE,msec,QS_ALLEVENTS)==WAIT_OBJECT_0) break;
}
}
}
BOOL waitForExit(unsigned timeout=INFINITE)
{
return standby(timeout,FALSE);
}
};
需要线程的地方就从它派生一个类,并实现run()方法.线程一般是运行在一个循环内,所以该类包含了一个循环.
struct worker : public thread
{
virtual BOOL run()
{
printf("in worker thread!/n");
return FALSE;
}
}
void main()
{
printf("in main thread!/n");
worker worker1;
worker1.start();
worker1.waitForExit();
}
这个线程类够简单了,就是每次使用的时候都需要派生一次,执行的函数总是自包含的,不时特别方便.下一篇给出一个改进的例子,使用外部的接口类来执行,而不需要从thread类派生.