定义临界区变量
CRITICAL_SECTION gCriticalSection;
通常情况下,CRITICAL_SECTION 结构体应该被定义为全局变量, 以便于进程中的所有线程方便地按照变量名来引用该结 构体。
初始化临界区
VOID WINAPI InitializeCriticalSection( LPCRITICAL_SECTION lpCriticalSection //指向程序员定义的CRITICAL_SECTION 变量 );
该函数用于对pcs 所指的 CRITICAL_SECTION 结构体进行初始化。该函数只是设置了一些成员变量,它的运行一般不会 失败,因此它采用了 VOID 类型的返回值。该函数必须在任何线程调用 EnterCriticalSection 函数之前被调用,如果一个线程试 图进入一个未初始化的 CRTICAL_SECTION,那么结果将是很难预计的。
删除临界区
VOID WINAPI DeleteCriticalSection( LPCRITICAL_SECTION lpCriticalSection //指向一个不再需要的 CRITICAL_SECTION 变量 );
进入临界区
VOID WINAPI EnterCriticalSection( LPCRITICAL_SECTION lpCriticalSection //指向一个你即将锁定的 CRITICAL_SECTION 变量 );
离开临界区
VOID WINAPI LeaveCriticalSection( LPCRITICAL_SECTION lpCriticalSection //指向一个你即将离开的 CRITICAL_SECTION 变量 );
使用临界区编程的一般方法是:
void UpdateData() { EnterCriticalSection(&gCriticalSection); ...//dosomething LeaveCriticalSection(&gCriticalSection); }
关于临界区的使用,有下列注意点:
(1)每个共享资源使用一个 CRITICAL_SECTION 变量;
(2)不要长时间运行关键代码段,当一个关键代码段长时间运行时,其他线程就会进入等待状态,这会降低应用程序的运
行性能;
(3)如果需要同时访问多个资源,则可能连续调用 EnterCriticalSection;
(4)CriticalSection 不是 OS核心对象,如果进入临界区的线程"挂"了,将无法释放临界资源。这个缺点在 Mutex 中得到 了弥补。
例子:
#include <Windows.h>
#include <process.h>
#include <stdio.h>
#include <stdlib.h>
int v = 0;//临界区数据
volatile bool stop_thread = false;
CRITICAL_SECTION g_CS;//锁
UINT WINAPI ThreadOneProc(LPVOID pParam)
{
while(!stop_thread)
{
EnterCriticalSection( &g_CS );//进入临界区
printf("one: %d\n",v++);
LeaveCriticalSection( &g_CS );//退出临界区
Sleep(500);
}
return 1;
}
UINT WINAPI ThreadTwoProc(LPVOID pParam)
{
while(!stop_thread)
{
EnterCriticalSection( &g_CS );
if (v>0)
{
printf("two: %d\n",v--);
}
LeaveCriticalSection( &g_CS );
Sleep(10);
}
return 2;
}
int main()
{
InitializeCriticalSection( &g_CS );//创建临界区
_beginthreadex(NULL,0,ThreadOneProc,0,0,0);//创建线程
_beginthreadex(NULL,0,ThreadTwoProc,0,0,0);
system("pause");
DeleteCriticalSection(&g_CS);
return 0;
}