【轉】用C++實現多線程Mutex鎖(Win32)

來源:互聯網
上載者:User

標籤:

原chexlong 原文地址:http://blog.csdn.net/chexlong/article/details/7051193

本文目的:用C++和Windows的互斥對象(Mutex)來實現線程同步鎖。

    準備知識:1,核心對象互斥體(Mutex)的工作機理,WaitForSingleObject函數的用法,這些可以從MSDN擷取詳情; 2,當兩個或更多線程需要同時訪問一個共用資源時,系統需要使用同步機制來確保一次只有一個線程使用該資源。Mutex 是同步基元,它只向一個線程授予對共用資源的獨佔訪問權。如果一個線程擷取了互斥體,則要擷取該互斥體的第二個線程將被掛起,直到第一個線程釋放該互斥體。

    下邊是我參考開源項目C++ Sockets的代碼,寫的線程鎖類

Lock.h

[cpp] view plaincopy
  1. #ifndef _Lock_H  
  2. #define _Lock_H  
  3.   
  4. #include <windows.h>  
  5.   
  6. //鎖介面類  
  7. class IMyLock  
  8. {  
  9. public:  
  10.     virtual ~IMyLock() {}  
  11.   
  12.     virtual void Lock() const = 0;  
  13.     virtual void Unlock() const = 0;  
  14. };  
  15.   
  16. //互斥對象鎖類  
  17. class Mutex : public IMyLock  
  18. {  
  19. public:  
  20.     Mutex();  
  21.     ~Mutex();  
  22.   
  23.     virtual void Lock() const;  
  24.     virtual void Unlock() const;  
  25.   
  26. private:  
  27.     HANDLE m_mutex;  
  28. };  
  29.   
  30. //鎖  
  31. class CLock  
  32. {  
  33. public:  
  34.     CLock(const IMyLock&);  
  35.     ~CLock();  
  36.   
  37. private:  
  38.     const IMyLock& m_lock;  
  39. };  
  40.   
  41.   
  42. #endif  

Lock.cpp

[cpp] view plaincopy
  1. #include "Lock.h"  
  2.   
  3. //建立一個匿名互斥對象  
  4. Mutex::Mutex()  
  5. {  
  6.     m_mutex = ::CreateMutex(NULL, FALSE, NULL);  
  7. }  
  8.   
  9. //銷毀互斥對象,釋放資源  
  10. Mutex::~Mutex()  
  11. {  
  12.     ::CloseHandle(m_mutex);  
  13. }  
  14.   
  15. //確保擁有互斥對象的線程對被保護資源的獨自訪問  
  16. void Mutex::Lock() const  
  17. {  
  18.     DWORD d = WaitForSingleObject(m_mutex, INFINITE);  
  19. }  
  20.   
  21. //釋放當前線程擁有的互斥對象,以使其它線程可以擁有互斥對象,對被保護資源進行訪問  
  22. void Mutex::Unlock() const  
  23. {  
  24.     ::ReleaseMutex(m_mutex);  
  25. }  
  26.   
  27. //利用C++特性,進行自動加鎖  
  28. CLock::CLock(const IMyLock& m) : m_lock(m)  
  29. {  
  30.     m_lock.Lock();  
  31. }  
  32.   
  33. //利用C++特性,進行自動解鎖  
  34. CLock::~CLock()  
  35. {  
  36.     m_lock.Unlock();  
  37. }  

    下邊是測試代碼

[cpp] view plaincopy
  1. // MyLock.cpp : 定義控制台應用程式的進入點。  
  2. //  
  3.   
  4. #include <iostream>  
  5. #include <process.h>  
  6. #include "Lock.h"  
  7.   
  8. using namespace std;  
  9.   
  10. //建立一個互斥對象  
  11. Mutex g_Lock;  
  12.   
  13.   
  14. //線程函數  
  15. unsigned int __stdcall StartThread(void *pParam)  
  16. {  
  17.     char *pMsg = (char *)pParam;  
  18.     if (!pMsg)  
  19.     {  
  20.         return (unsigned int)1;  
  21.     }  
  22.   
  23.     //對被保護資源(以下列印語句)自動加鎖  
  24.     //線程函數結束前,自動解鎖  
  25.     CLock lock(g_Lock);  
  26.   
  27.     for( int i = 0; i < 5; i++ )  
  28.     {  
  29.         cout << pMsg << endl;  
  30.         Sleep( 500 );  
  31.     }  
  32.   
  33.     return (unsigned int)0;  
  34. }  
  35.   
  36. int main(int argc, char* argv[])  
  37. {  
  38.     HANDLE hThread1, hThread2;  
  39.     unsigned int uiThreadId1, uiThreadId2;  
  40.   
  41.     char *pMsg1 = "First print thread.";  
  42.     char *pMsg2 = "Second print thread.";  
  43.   
  44.     //建立兩個背景工作執行緒,分別列印不同的訊息  
  45.   
  46.     //hThread1 = ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)StartThread, (void *)pMsg1, 0, (LPDWORD)&uiThreadId1);  
  47.     //hThread2 = ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)StartThread, (void *)pMsg2, 0, (LPDWORD)&uiThreadId2);  
  48.   
  49.     hThread1 = (HANDLE)_beginthreadex(NULL, 0, &StartThread, (void *)pMsg1, 0, &uiThreadId1);  
  50.     hThread2 = (HANDLE)_beginthreadex(NULL, 0, &StartThread, (void *)pMsg2, 0, &uiThreadId2);  
  51.   
  52.     //等待線程結束  
  53.     DWORD dwRet = WaitForSingleObject(hThread1,INFINITE);  
  54.     if ( dwRet == WAIT_TIMEOUT )  
  55.     {  
  56.         TerminateThread(hThread1,0);  
  57.     }  
  58.     dwRet = WaitForSingleObject(hThread2,INFINITE);  
  59.     if ( dwRet == WAIT_TIMEOUT )  
  60.     {  
  61.         TerminateThread(hThread2,0);  
  62.     }  
  63.   
  64.     //關閉線程控制代碼,釋放資源  
  65.     ::CloseHandle(hThread1);  
  66.     ::CloseHandle(hThread2);  
  67.   
  68.     system("pause");  
  69.     return 0;  
  70. }  

    用VC2005編譯,啟動程式,下邊是

 

    如果將測線程函數中的代碼注視掉,重新編譯代碼,運行

[cpp] view plaincopy
  1. CLock lock(g_Lock);  

     則結果見

 

    由此可見,通過使用Mutex的封裝類,即可達到多線程同步的目的。因Mutex屬於核心對象,所以在進行多線程同步時速度會比較慢,但是用互斥對象可以在不同進程的多個線程之間進行同步。

    在實際應用中,我們通常還會用到臨界區,也有叫做關鍵程式碼片段的CRITICAL_SECTION,在下篇部落格中,我將會把CRITICAL_SECTION鎖添加進來,並且對Mutex和CRITICAL_SECTION的效能做以比較。

【轉】用C++實現多線程Mutex鎖(Win32)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.