多线程通讯--临界区

临界区:是一段供县城独占访问的代码,也就是说如果有一线程正在访问该代码段,其他线程必须等该线程离开该代码段方可进入,这样保证了线程安全,他用于用户级(相对于内核级),在windows系统中CRITICAL_SECTION实现临界区相关机制


下一个临界区最多管理 64个线程


相关函数:

void InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection)  // 初始化临界区

void EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection)       // 进入临界区

void LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection)       // 离开临界区

void DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection)      // 释放临界区资源


使用实例:

代码不精确

#include<windows.h>

CRITICAL_SECTIONcs;//定义临界区对象,结构体变量


//定义全局变量
int num = 0; 

void  run()
{
    EnterCriticalSection(&cs);//进入临界区,其它线程则无法进入
    
    //安全访问该区域
    int i = 0;
    
    for(i = 0 ; i < 10000 ; i ++)
        {
            num++ 
        }
        
    LeaveCriticalSection(&cs);//离开临界区,其它线程可以进入
}

int main()
{

    //在进入多线程环境之前,初始化临界区
    InitializeCriticalSection(&cs);
    
    HANDLE  hd[10];
    int i = 0;
    for(i = 0 ; i < 10 ;i++)
    {
        hd[i]  = creadthread(NULL, 0, run,NULL,0,NULL);
    }
    WaitForMultipleObjects(10,hd,TURE,INFINITE);//等待所有 线程结束,主线程才结束;
    
    printf("num = %d\n",num);
    //释放临界区资源,当不再使用临界区时调用该函数
    DeleteCriticalSection(&cs);
    
}


临界区的应用
EnterCriticalSection和LeaveCriticalSection跟new/delete一样是成对调用的,很多时候在调用EnterCriticalSection以后不得不在多处加入LeaveCriticalSection,因为临界区内有return,break,continue,goto等等跳转,一不小心就会造成死锁。基于这个原因,在很多开源代码中都对CRITICAL_SECTION进行了封装。下面是我从某开源库中摘取的封装后的代码:


classMutex{
public:
    Mutex()  {InitializeCriticalSection(§ion);}
    ~Mutex() {DeleteCriticalSection(§ion);}
    void Enter()  {EnterCriticalSection(§ion);}
    void Leave()  {LeaveCriticalSection(§ion);}

    struct Lock;
protected:
    Mutex(const Mutex&);
    Mutex&  operator=(const Mutex&);

    CRITICAL_SECTION section;
};

struct  Mutex::Lock
{
    Mutex&s;
    Lock(Mutex&s):s(s){s.Enter();}
    ~Lock(){s.Leave();}
};
 
 
上面Mutex封装了CRITICAL_SECTION相关的四个函数,Mutex的对象可作为类的non-static成员,这样通过Mutex的构造和析构执行InitializeCriticalSection和DeleteCriticalSection。
 在进入临界区的地方(函数体内)定义Mutex::Lock的对象作为局部变量,通过Mutex::Lock对象的生命周期控制临界区范围。 

使用示例:

  1. class A{  
  2. public:  
  3.   void Foo();  
  4. private:  
  5.   Mutex mutex;  
  6. };  
  7.   
  8. void A::Foo()  
  9. {    
  10.   Mutex::Lock lock(mutex);  
  11.   // 临界区代码  
  12. }  




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值