临界区操作
概念:
让我先对同步(synchronous)与异步(asynchronous)做个说明。当程序1调
用程序2时,程序1停下不动,直到程序2完成回到程序1来,程序1才继
续下去,这就是所谓的“synchronous”。如果程序1调用程序2后,径自继
续自己的下一个动作,那么两者之间就是所谓的“asynchronous ”。Win32 API
中的 SendMessage() 就是同步行为,而PostMessage() 就是异步行为。
本文先给出小段代码,后给出综合的大段完整代码。
Win32 中关于进程和线程的协调工作是由同步机制(synchronous
mechanism)来完成的。
Win32 之中最容易使用的一个同步机制就是critical sections 。所谓
criticalsections 意指一小块“用来处理一份被共享之资源”的程序代码。
你不需要使用像“Create”这样的 API 函数获得一个 critical section handle。你应该做的是将一个类型为 :CRITICAL_SECTION 的局部变量初始化
方法是调用 :InitializeCriticalSection()
2个重要的函数:
VOIDInitializeCriticalSection(
LPCRITICAL_SECTION lpCriticalSection
);
参数 :
lpCriticalSection 一个指针,指向欲被初始化的
CRITICAL_SECTION 变量。这个变量应该在你的程序中定义。
返回值 :
此函数传回 void 。
当你用毕 critical section 时,你必须调用DeleteCriticalSection()清除它。这个函数并没有“释放对象”的意义在里头,不要把它和 C++ 的 delete 运算符混淆了。
VOIDDeleteCriticalSection(
LPCRITICAL_SECTION lpCriticalSection
);
参数:
lpCriticalSection 指向一个不再需要的CRITICAL_SECTION 变量。
返回值 :
此函数传回 void 。
函数的使用:
CRITICAL_SECTIONgCriticalSection;
…………
voidCreateDeleteCriticalSection()
{
InitializeCriticalSection(&gCriticalSection);
/* Do something here */
DeleteCriticalSection(&gCriticalSection);
}
一旦 critical section 被初始化,每一个线程就可以进入其中——只要它通
过了 EnterCriticalSection() 这一关。
另外1个函数:
VOIDEnterCriticalSection(
LPCRITICAL_SECTION lpCriticalSection
);
参数:
lpCriticalSection 指向一个你即将锁定的CRITICAL_SECTION 变量。
返回值 :
此函数传回 void 。
当线程准备好要离开 critical section 时,它必须调用LeaveCriticalSection() :
另外1个函数:
VOIDLeaveCriticalSection(
LPCRITICAL_SECTION lpCriticalSection
);
参数 :
lpCriticalSection 指向一个你即将解除锁定的CRITICAL_SECTION 变量。
返回值 :
此函数传回 void 。
函数的综合使用:
voidUpdateData()
{
EnterCriticalSection(&gCriticalSection);
/* Update the resource临界区的代码*/
LeaveCriticalSection(&gCriticalSection);
}
想要操作临界区,必须先enter,然后记得leave,这样,同一时刻只有一个线程可以访问临界区,哪怕是抢占式系统。
Win32critical section 的另一个性质:
一旦线程进入一个critical section ,它就能够一再地重复进入该critical section 。