先看如下代碼:(用Visual Studio 2010按照Win32 Console程序創建嚮導創建)
1 #include "stdafx.h" 2 3 #include <process.h> 4 #include <windows.h> 5 #include <iostream> 6 7 #include <stdio.h> 8 #include <stdlib.h> 9 10 using namespace std; 11 12 UINT WINAPI ThreadA(void *args); 13 UINT WINAPI ThreadB(void *args); 14 15 static CRITICAL_SECTION gCS = {0}; 16 17 int _tmain(int argc, _TCHAR* argv[]) 18 { 19 DWORD dwWait = 0; 20 21 InitializeCriticalSection(&gCS); 22 HANDLE threadA_handle = (HANDLE)_beginthreadex(NULL, 0, ThreadA, NULL, CREATE_SUSPENDED, NULL); 23 HANDLE threadB_handle = (HANDLE)_beginthreadex(NULL, 0, ThreadB, NULL, CREATE_SUSPENDED, NULL); 24 25 26 if (INVALID_HANDLE_VALUE == threadA_handle) 27 { 28 cout << GetLastError() << endl; 29 } 30 31 ResumeThread(threadA_handle); 32 ResumeThread(threadB_handle); 33 34 HANDLE handleArry[2] = {threadA_handle, 35 threadB_handle}; 36 37 dwWait = WaitForMultipleObjects(2, handleArry, true, 10000); 38 cout << dwWait << " " << GetLastError() << endl; 39 40 DeleteCriticalSection(&gCS); 41 CloseHandle(threadA_handle); 42 CloseHandle(threadB_handle); 43 44 return 0; 45 } 46 47 UINT WINAPI ThreadA(void *args) 48 { 49 UINT i = 0; 50 EnterCriticalSection(&gCS); 51 for (i=0; i<10; ++i) 52 { 53 cout << "A: " << i << endl; 54 } 55 cout << endl; 56 LeaveCriticalSection(&gCS); 57 58 return 0; 59 } 60 61 UINT WINAPI ThreadB(void *args) 62 { 63 UINT j = 0; 64 EnterCriticalSection(&gCS); 65 for (j=0; j<10; ++j) 66 { 67 cout << "B: " << j << endl; 68 } 69 cout << endl; 70 LeaveCriticalSection(&gCS); 71 return 0; 72 }
【總結】:
關鍵段屬於用戶態下的線程同步方式,因此比較快;
關鍵段用於兩個互斥的線程,以保證每個線程獨佔資源,這種應用的場景舉例如下:
- 線程A用於實時響應用戶的請求訪問一個資源;
- 線程B用於週期性地訪問同一個資源;
- 爲了保證資源不被破壞,可以採用關鍵段的方式,同一時刻只允許一個線程訪問同一個資源;
- 採用線程優先級的方式(線程B的優先級低於線程A)無法實現上述要求,因爲Windows系統採用搶佔式多線程方式,因此當線程B訪問資源時,線程A可以搶佔CPU訪問同一個資源,那麼當線程B可以訪問同一個資源時,該資源可能已經被修改了;
【參考】