先看如下代码:(用Visual Studio 2010按照Win32 Console程序创建向导创建)
#include "stdafx.h" #include <process.h>
#include <windows.h>
#include <iostream> #include <stdio.h>
#include <stdlib.h> using namespace std; UINT WINAPI ThreadA(void *args);
UINT WINAPI ThreadB(void *args); static CRITICAL_SECTION gCS = {}; int _tmain(int argc, _TCHAR* argv[])
{
DWORD dwWait = ; InitializeCriticalSection(&gCS);
HANDLE threadA_handle = (HANDLE)_beginthreadex(NULL, , ThreadA, NULL, CREATE_SUSPENDED, NULL);
HANDLE threadB_handle = (HANDLE)_beginthreadex(NULL, , ThreadB, NULL, CREATE_SUSPENDED, NULL); if (INVALID_HANDLE_VALUE == threadA_handle)
{
cout << GetLastError() << endl;
} ResumeThread(threadA_handle);
ResumeThread(threadB_handle); HANDLE handleArry[] = {threadA_handle,
threadB_handle}; dwWait = WaitForMultipleObjects(, handleArry, true, );
cout << dwWait << " " << GetLastError() << endl; DeleteCriticalSection(&gCS);
CloseHandle(threadA_handle);
CloseHandle(threadB_handle); return ;
} UINT WINAPI ThreadA(void *args)
{
UINT i = ;
EnterCriticalSection(&gCS);
for (i=; i<; ++i)
{
cout << "A: " << i << endl;
}
cout << endl;
LeaveCriticalSection(&gCS); return ;
} UINT WINAPI ThreadB(void *args)
{
UINT j = ;
EnterCriticalSection(&gCS);
for (j=; j<; ++j)
{
cout << "B: " << j << endl;
}
cout << endl;
LeaveCriticalSection(&gCS);
return ;
}
【总结】:
关键段属于用户态下的线程同步方式,因此比较快;
关键段用于两个互斥的线程,以保证每个线程独占资源,这种应用的场景举例如下:
- 线程A用于实时响应用户的请求访问一个资源;
- 线程B用于周期性地访问同一个资源;
- 为了保证资源不被破坏,可以采用关键段的方式,同一时刻只允许一个线程访问同一个资源;
- 采用线程优先级的方式(线程B的优先级低于线程A)无法实现上述要求,因为Windows系统采用抢占式多线程方式,因此当线程B访问资源时,线程A可以抢占CPU访问同一个资源,那么当线程B可以访问同一个资源时,该资源可能已经被修改了;
【参考】