【win32多線程】使用C++編寫多線程

來源:互聯網
上載者:User
1.以一個C++對象啟動一個線程
 Q:如何以一個C++成員函數當做線程的起始函數。
 
錯誤的例子
#include <windows.h>#include <stdio.h>#include <process.h>typedef unsigned (WINAPI *PBEGINTHREADEX_THREADFUNC)(    LPVOID lpThreadParameter    );typedef unsigned *PBEGINTHREADEX_THREADID;class ThreadObject{public:    ThreadObject();    void StartThread();    virtual DWORD WINAPI ThreadFunc(LPVOID param);    void WaitForExit();private:    HANDLE  m_hThread;    DWORD m_ThreadId;};ThreadObject::ThreadObject(){    m_hThread = NULL;    m_ThreadId = 0;}void ThreadObject::StartThread(){    m_hThread = (HANDLE)_beginthreadex(NULL,                            0,                            (PBEGINTHREADEX_THREADFUNC)ThreadFunc,                            0,                            0,                            (PBEGINTHREADEX_THREADID)&m_ThreadId );    if (m_hThread) {        printf("Thread launched\n");    }}void ThreadObject::WaitForExit(){    WaitForSingleObject(m_hThread, INFINITE);    CloseHandle(m_hThread);}DWORD WINAPI ThreadObject::ThreadFunc(LPVOID param) //對類的成員函數預設有一個this參數{    // Do something useful ...    return 0;}void main(){    ThreadObject obj;    obj.StartThread();    obj.WaitForExit();}

正確的做法
為了以一個成員函數啟動一個線程,要麼使用靜態成員函數,要麼使用C函數,而非C++成員函數。這兩種


技術的本質是相同的,但是靜態成員函數的一個優點就是,它能夠處理類的private成員變數和protected


成員變數。


由一個成員函數來啟動一個線程範例:
#define WIN32_LEAN_AND_MEAN#include <stdio.h>#include <stdlib.h>#include <windows.h>#include <process.h>typedef unsigned (WINAPI *PBEGINTHREADEX_THREADFUNC)(    LPVOID lpThreadParameter    );typedef unsigned *PBEGINTHREADEX_THREADID;//// This ThreadObject is created by a thread// that wants to start another thread. All// public member functions except ThreadFunc()// are called by that original thread. The// virtual function ThreadMemberFunc() is// the start of the new thread.//class ThreadObject{public:    ThreadObject();    void StartThread();    void WaitForExit();    static DWORD WINAPI ThreadFunc(LPVOID param);protected:    virtual DWORD ThreadMemberFunc();    HANDLE  m_hThread;    DWORD   m_ThreadId;};ThreadObject::ThreadObject(){    m_hThread = NULL;    m_ThreadId = 0;}void ThreadObject::StartThread(){    m_hThread = (HANDLE)_beginthreadex(NULL,        0,        (PBEGINTHREADEX_THREADFUNC) ThreadObject::ThreadFunc,        (LPVOID)this,        0,        (PBEGINTHREADEX_THREADID) &m_ThreadId );    if (m_hThread) {        printf("Thread launched\n");    }}void ThreadObject::WaitForExit(){    WaitForSingleObject(m_hThread, INFINITE);    CloseHandle(m_hThread);}//// This is a static member function.  Unlike// C static functions, you only place the static// declaration on the function declaration in the// class, not on its implementation.//// Static member functions have no "this" pointer,// but do have access rights.//DWORD WINAPI ThreadObject::ThreadFunc(LPVOID param){    // Use the param as the address of the object    ThreadObject* pto = (ThreadObject*)param;    // Call the member function. Since we have a    // proper object pointer, even virtual functions    // will be called properly.    return pto->ThreadMemberFunc();}//// This above function ThreadObject::ThreadFunc()// calls this function after the thread starts up.//DWORD ThreadObject::ThreadMemberFunc(){    // Do something useful ...    return 0;}void main(){    ThreadObject obj;    obj.StartThread();    obj.WaitForExit();}在C++中如何利用建構函式和解構函式寫一個比較安全的多線程程式,以及如何利用虛函數和多態等性質做出一個可互換的鎖定機制。在C++中封裝一個Critical sectionclass CriticalSection{public:CriticalSection();~CriticalSection();void Enter();void Leave();private:CRITICAL_SECTION m_CritSect;}CriticalSection::CriticalSection(){InitializeCriticalSection(&m_CritSect);}CriticalSection::~CriticalSection(){DeleteCriticalSection(&m_CritSect);}CriticalSection::Enter(){ EnterCriticalSection(&m_CritSect);}CriticalSection::Leave(){ LeaveCriticalSection(&m_CritSect);}在String類中使用CriticalSection類Class String{  public:  String();  virtual ~String();  virtual void Set(char *str);int GetLength();private:CriticalSection m_Sync;char * m_pData;};String::String(){ m_pData=NULL;}String::~String(){m_Sync.Enter();delete []m_pData;m_Sync.Leave();}void String::Set(char *str){m_Sync.Enter();delete [] m_pData;m_pData=new char[::strlen(str)+1];::strcpy(m_pData,str);m_Sync.Leave();}int String::GetLength(){if(m_pData==NULL)return 0;m_Sync.Enter();int len=::strlen(m_pData);m_Sync.Leave();return len;}

這樣就可以聲明一個String變數,完全可以不瞭解Critical section,就可以獲得同步效果。

----建立抽象的同步化對象
class Lock{ public:Lock(CriticalSection *pCritsect);~Lock();private:CriticalSection *m_pCritical;};Lock::Lock(CriticalSection *pCritsect){m_pCritical=pCritsect;EnterCriticalSection(&m_pCritical);}Lock::~Lock(){LeaveCriticalSection(&m_pCritical);}

這個解構函式可以被自動調用,而critical section會被自動地解除鎖定。絕對不會忘記將critical 

section解除鎖定。

-------建立可互換的Lock

class LockableObject{public:    LockableObject() {}virtual ~ LockableObject(){}virtual void Lock()=0;virtual void UnLock()=0;};public CriticalSectionV2: public LockableObject{CriticalSectionV2();virtual ~CriticalSectionV2();virtual void Lock();virtual void UnLock();private:CRITICAL_SECTION m_CritSect;};CriticalSectionV2::CriticalSectionV2(){InitializeCriticalSection(&m_CritSect);}CriticalSectionV2::~CriticalSectionV2(){DeleteCriticalSection(&m_CritSect);}CriticalSectionV2::Lock(){ EnterCriticalSection(&m_CritSect);}CriticalSectionV2::UnLock(){LeaveCriticalSection(&m_CritSect);}建立一個極安全又簡單的Lockclass LockV2{public:   LockV2(LockableObject *pLockable);~LockV2();private:LockableObject * m_pLockable;};LockV2::LockV2(LockableObject *pLockable){m_pLockable=pLockable;m_pLockable->Lock();}LockV2::~LockV2(){ m_pLockable->UnLock();}
上面用C++類取代Win32 API的直接調用
用安全又簡單的“Lock”重寫String 類
class StringV2{public:StringV2();virtual ~StringV2();virtual void Set(char * str);int getLength();private:CriticalSectionV2 m_Lockable;char * m_pData;};StringV2::StringV2(){ m_pData=NULL;}StringV2::~StringV2(){delete [] m_pData;}void StringV2::Set(char *str){LockV2 localLock(&m_Lockable);delete [] m_pData; m_pData=NULL;m_pData=new char[strlen(str)+1];strcpy(m_pData,str);}int String::GetLength(){ LockV2 localLock(&m_Lockable);if(m_pData==NULL)return 0;return ::strlen(m_pData);}

複製 搜尋 複製 搜尋
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.