编程野路:多线编程之二,一个线程类

来源:互联网 发布:战地4网络需求 编辑:程序博客网 时间:2024/06/09 14:30
以下是一个线程类的实现:
#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类派生.
原创粉丝点击