Windows多線程中關鍵段(Critical Section)的應用

先看如下代碼:(用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 }

【總結】:

關鍵段屬於用戶態下的線程同步方式,因此比較快;

關鍵段用於兩個互斥的線程,以保證每個線程獨佔資源,這種應用的場景舉例如下:

  1. 線程A用於實時響應用戶的請求訪問一個資源;
  2. 線程B用於週期性地訪問同一個資源;
  3. 爲了保證資源不被破壞,可以採用關鍵段的方式,同一時刻只允許一個線程訪問同一個資源;
  4. 採用線程優先級的方式(線程B的優先級低於線程A)無法實現上述要求,因爲Windows系統採用搶佔式多線程方式,因此當線程B訪問資源時,線程A可以搶佔CPU訪問同一個資源,那麼當線程B可以訪問同一個資源時,該資源可能已經被修改了;

【參考】

  1. Windows核心編程(第5版)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章