Windows多线程中关键段(Critical Section)的应用

时间:2023-03-10 06:49:43
Windows多线程中关键段(Critical Section)的应用

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

【总结】:

关键段属于用户态下的线程同步方式,因此比较快;

关键段用于两个互斥的线程,以保证每个线程独占资源,这种应用的场景举例如下:

  1. 线程A用于实时响应用户的请求访问一个资源;
  2. 线程B用于周期性地访问同一个资源;
  3. 为了保证资源不被破坏,可以采用关键段的方式,同一时刻只允许一个线程访问同一个资源;
  4. 采用线程优先级的方式(线程B的优先级低于线程A)无法实现上述要求,因为Windows系统采用抢占式多线程方式,因此当线程B访问资源时,线程A可以抢占CPU访问同一个资源,那么当线程B可以访问同一个资源时,该资源可能已经被修改了;

【参考】

  1. Windows核心编程(第5版)