1. 程式人生 > >Windows執行緒同步之互斥鎖(Mutex)

Windows執行緒同步之互斥鎖(Mutex)

執行緒同步的方式和機制

臨界區、互斥區、事件、訊號量四種方式

臨界區(Critical Section)、互斥量(Mutex)、訊號量(Semaphore)、事件(Event)的區別

1、臨界區:通過對多執行緒的序列化來訪問公共資源或一段程式碼,速度快,適合控制資料訪問。在任意時刻只允許一個執行緒對共享資源進行訪問,如果有多個執行緒試圖訪問公共資源,那麼在有一個執行緒進入後,其他試圖訪問公共資源的執行緒將被掛起,並一直等到進入臨界區的執行緒離開,臨界區在被釋放後,其他執行緒才可以搶佔。

2、互斥量:採用互斥物件機制。 只有擁有互斥物件的執行緒才有訪問公共資源的許可權,因為互斥物件只有一個,所以能保證公共資源不會同時被多個執行緒訪問。互斥不僅能實現同一應用程式的公共資源安全共享,還能實現不同應用程式的公共資源安全共享

3、訊號量:它允許多個執行緒在同一時刻訪問同一資源,但是需要限制在同一時刻訪問此資源的最大執行緒數目

4、事 件: 通過通知操作的方式來保持執行緒的同步,還可以方便實現對多個執行緒的優先順序比較的操作

在這裡我們要講的互斥鎖,像一個物件,這個物件只能同時被一個執行緒持有。如此一來,便可以通過互斥鎖來實現執行緒的同步

一、建立
建立互斥鎖的方法是呼叫函式CreateMutex:
CreateMutex(&sa, bInitialOwner, szName);第一個引數是一個指向SECURITY_ATTRIBUTES結構體的指標,一般的情況下,可以是nullptr。
第二個引數型別為BOOL,表示互斥鎖創建出來後是否被當前執行緒持有。
第三個引數型別為字串(const TCHAR*),是這個互斥鎖的名字,如果是nullptr,則互斥鎖是匿名的。
例:
HANDLE hMutex = CreateMutex(nullptr, FALSE, nullptr);上面的程式碼建立了一個匿名的互斥鎖,創建出來後,當前執行緒不持有這個互斥鎖。


二、持有
WaitForSingleObject函式可以讓一個執行緒持有互斥鎖。用法:
WaitForSingleObject(hMutex, dwTimeout);這個函式的作用比較多。這裡只介紹第一個引數為互斥鎖控制代碼時的作用。
它的作用是等待,直到一定時間之後,或者,其他執行緒均不持有hMutex。第二個引數是等待的時間(單位:毫秒),如果該引數為INFINITE,則該函式會一直等待下去。


三、釋放
用ReleaseMutex函式可以讓當前執行緒“放開”一個互斥鎖(不持有它了),以便讓其他執行緒可以持有它。用法
ReleaseMutex(hMutex);

四、銷燬
當程式不再需要互斥鎖時,要銷燬它。
CloseHandle(hMutex);

五、命名互斥鎖
如果CreateMutex函式的第三個引數傳入一個字串,那麼所建立的鎖就是命名的。當一個命名的鎖被創建出來以後,當前程序和其他程序如果試圖建立相同名字的鎖,CreateMutex會返回原來那把鎖的控制代碼,並且GetLastError函式會返回ERROR_ALREADY_EXISTS。這個特點可以使一個程式在同一時刻最多執行一個例項。

  1. BOOL CDemoDlg::OnInitDialog()  
  2. {  
  3.     HANDLE hMutex = CreateMutex(nullptr, FALSE, "Demo");  
  4.     if (GetLastError() == ERROR_ALREADY_EXISTS) // 已經有了一個例項
  5.     {  
  6.         MessageBox("只能有一個應用程式在執行!","Demo");  
  7.         exit(0);  
  8.     }  
  9.     // 其他程式碼
  10.     return TRUE;  
  11. }