关键代码段
关键代码段,也叫做临界区,它是指包含共享资源的一小段代码,这段代码被执行前需要得到访问权才能被执行,否则会一直等到;
相关API
- 初始化关键代码段对象
void WINAPI InitializeCriticalSection(
__out LPCRITICAL_SECTION lpCriticalSection
);
- 等待关键代码段对象的所有权
void WINAPI EnterCriticalSection(
__inout LPCRITICAL_SECTION lpCriticalSection
);
- 释放关键代码段对象的所有权
void WINAPI LeaveCriticalSection(
__inout LPCRITICAL_SECTION lpCriticalSection
);
- 释放为关键代码段分配的所有资源
void WINAPI DeleteCriticalSection(
__inout LPCRITICAL_SECTION lpCriticalSection
);
使用规则:
先定义一个 CRITICAL_SECTION 的全局对象,然后用InitializeCriticalSection初始化该对象;在线程函数中的关键代码段前使用EnterCriticalSection函数获得所有权,离开关键代码后使用LeaveCriticalSection函数释放所有权;在程序的最后需要利用DeleteCriticalSection为关键代码段对象释放所有的系统资源;
具体代码
#include "stdafx.h"
#include <iostream>
#include <afxmt.h>
using namespace std;
int g_nIndex = 0;
const int nMaxCnt = 20;
CRITICAL_SECTION g_csLock;
//线程函数1
DWORD WINAPI Thread1SynByCS(LPVOID lpParameter)
{
while (TRUE)
{
//等待直到获得指定对象的所有权
EnterCriticalSection(&g_csLock);
//关键代码段-begin
if (g_nIndex++ < nMaxCnt)
{
cout << "Index = "<< g_nIndex << " ";
cout << "Thread2 is runing" << endl;
//权限释放
LeaveCriticalSection(&g_csLock);
}
else
{
//权限释放
LeaveCriticalSection(&g_csLock);
//关键代码段-end
break;
}
}
return 0;
}
//线程函数2
DWORD WINAPI Thread2SynByCS(LPVOID lpParameter)
{
while (TRUE)
{
//等待直到获得指定对象的所有权
EnterCriticalSection(&g_csLock);
//关键代码段-begin
if (g_nIndex++ < nMaxCnt)
{
cout << "Index = "<< g_nIndex << " ";
cout << "Thread2 is runing" << endl;
//权限释放
LeaveCriticalSection(&g_csLock);
}
else
{
//权限释放
LeaveCriticalSection(&g_csLock);
//关键代码段-end
break;
}
}
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hThread1 = NULL;
HANDLE hThread2 = NULL;
//初始化关键代码段对象
InitializeCriticalSection(&g_csLock);
//创建新的线程
hThread1 = CreateThread(NULL,0,Thread1SynByCS,NULL,0,NULL);//立即执行
hThread2 = CreateThread(NULL,0,Thread2SynByCS,NULL,0,NULL);//立即执行
//无须对新线程设置优先级等操作,关闭之
//良好的编码习惯
CloseHandle(hThread1);
CloseHandle(hThread2);
Sleep(3000);
//释放为关键代码段对象分配的所有资源
DeleteCriticalSection(&g_csLock);
return 0;
}
运行结果
从运行结果可以看出,程序执行是按照预期的流程进行,没有异常现象