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 }
【总结】:
关键段属于用户态下的线程同步方式,因此比较快;
关键段用于两个互斥的线程,以保证每个线程独占资源,这种应用的场景举例如下:
- 线程A用于实时响应用户的请求访问一个资源;
- 线程B用于周期性地访问同一个资源;
- 为了保证资源不被破坏,可以采用关键段的方式,同一时刻只允许一个线程访问同一个资源;
- 采用线程优先级的方式(线程B的优先级低于线程A)无法实现上述要求,因为Windows系统采用抢占式多线程方式,因此当线程B访问资源时,线程A可以抢占CPU访问同一个资源,那么当线程B可以访问同一个资源时,该资源可能已经被修改了;
【参考】
版权声明:
作者:朝雾之归乡
出处:http://www.cnblogs.com/cnpirate
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。