基于临界区的线程同步

Windows操作系统提供了设定“特殊事件”的方法,就是使用同步对象。我将在今后学习常用的四种同步对象:临界区(Critical Section)、互斥量(Mutex)、信号量(Semaphore)、事件(Event)。

        上述四种同步对象,除了临界区外都是内核对象。临界区不被操作系统的低级部件管理,而且不能使用句柄来操纵,是最易于使用和理解的同步对象。临界区工作在用户方式下,速度较快,但是容易进入死锁。

        当多个线程共享对同一数据的访问时,线程之间可能会有干扰。一个临界区对象保护一段代码不被多于一个线程访问。在所有的同步对象中,临界区是最容易使用的,但是,一个临界区对一个进程或DLL是有限的,不能被其他进程共享,只能用于同步单个进程中的线程。临界区不是Windows核心对象,它和核心对象不同,存在于进程的内存空间中

        Win32 API提供了几个临界区函数:

void  InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
void  EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
void  LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
void  DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection);

        CRITICAL_SECTION类型的变量用来扮演红绿灯的角色,让同一个时间内只有一个线程进入临界区。该临界区变量的声明必须是全局的,这样不同的线程就能访问它。操纵临界区的Win32函数初始化和维护该结构中的所有成员,不要自己去访问和修改任何成员。

        使用临界区之前,必须调用InitializeCriticalSection()函数来初始化临界区。而通过调用EnterCriticalSection()函数来取得一个临界区的所有权。然后通过LeaveCriticalSection()函数来释放所有权。临界区通过一个线程取得所有权来显示它已经进入代码临界区的方法进行工作,如果其他线程调用EnterCriticalSection()并引用同一临界区,它会被阻塞,直到第一个线程调用LeaveCriticalSection()函数。最后,可以调用DeleteCriticalSection()函数来释放用户初始化临界区时分配的系统资源。

        下面有个具体的应用例子:

[cpp]  view plain copy
  1. #include <iostream>  
  2. #include "windows.h"  
  3. using namespace std;  
  4.   
  5. DWORD WINAPI funpro1(LPVOID lpParenrer);  
  6. DWORD WINAPI funpro2(LPVOID lpParenter);  
  7. int time = 0 ;  
  8. CRITICAL_SECTION critical;  
  9.   
  10. int main()  
  11. {  
  12.     HANDLE handle1,handle2;  
  13.     handle1 = CreateThread(NULL,0,funpro1,NULL,0,NULL);  
  14.     handle2 = CreateThread(NULL,0,funpro2,NULL,0,NULL);  
  15.     CloseHandle(handle1);  
  16.     CloseHandle(handle2);  
  17.     InitializeCriticalSection(&critical);  
  18.   
  19.     Sleep(3000);  
  20.     DeleteCriticalSection(&critical);  
  21.     system("pause");  
  22.     return 0;  
  23. }  
  24.   
  25. DWORD WINAPI funpro1(LPVOID lpParenrer)  
  26. {  
  27.     while (1)  
  28.     {  
  29.         EnterCriticalSection(&critical);  
  30.         if (time<=20)  
  31.         {  
  32.             cout<<"子线程1:"<<time++<<endl;  
  33.         }  
  34.         else break;  
  35.         LeaveCriticalSection(&critical);  
  36.     }  
  37.     return 0;  
  38. }  
  39.   
  40. DWORD WINAPI funpro2(LPVOID lpParenter)  
  41. {  
  42.     while (1)  
  43.     {  
  44.         EnterCriticalSection(&critical);  
  45.         if (time<=20)  
  46.         {  
  47.             cout<<"子线程2:"<<time++<<endl;  
  48.         }  
  49.         else break;  
  50.         LeaveCriticalSection(&critical);  
  51.     }  
  52.     return 0;  
  53. }  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值