C++ 线程同步之临界区CRITICAL_SECTION

一、临界区

临界区又称关键代码段,指的是一小段代码在代码执行前,它需要独占一些资源,只能在单独的进程中使用。程序中通常将多线程同时访问的某个资源的程序片段称为临界区。需要定义一个CRITICAL_SECTION类型的变量,然后调用InitializeCriticalSection函数对变量进行初始化。相对于互斥量来说,系统分配临界区对象的速度更快,所需的开销更小。

二、实例

定义一个全局的锁 CRITICAL_SECTION的实例和一个静态全局变量

    CRITICAL_SECTIONcs;// 临界区的声明
    static intn_AddValue = 0;//定义一个静态的全部变量n_AddValue

创建两个线程函数,代码实现如下 

    //第一个线程
    UINT FirstThread(LPVOIDlParam)
    {
        EnterCriticalSection(&cs);//进入临界区,对需要保护的资源进行操作
        for(int i =0; i<10;i++){       
            n_AddValue ++;
            cout <<"n_AddValue in FirstThread is"<<n_AddValue << endl;       
       
        }
        LeaveCriticalSection(&cs);//离开临界区   
        return 0;
     
    }
     
    //第二个线程
    UINT SecondThread(LPVOIDlParam)
    {
        EnterCriticalSection(&cs);//进入临界区
        for(int i =0; i<10;i++){       
            n_AddValue ++;       
            cout <<"n_AddValue in SecondThread is"<<n_AddValue << endl;   
           
        }
        LeaveCriticalSection(&cs);//离开临界区
     
        return 0;
     
    }

 在主函数添加以下代码

CWinThread *pFirstThread, *pSecondThread;//存储函数AfxBeginThread返回的CWinThread指针

	InitializeCriticalSection(&cs);//初始化临界区
	pFirstThread = AfxBeginThread(test->FirstThread, LPVOID(NULL));//启动第一个线程
	pSecondThread = AfxBeginThread(test->SecondThread, LPVOID(NULL));//启动第二个线程

	HANDLE hThreadHandle[2];//
	hThreadHandle[0] = pFirstThread->m_hThread;
	hThreadHandle[1] = pSecondThread->m_hThread;

	//等待线程返回
	WaitForMultipleObjects(2, hThreadHandle, TRUE, INFINITE);

三、临界区的原理

很多人对CRITICAL_SECTION的理解是错误的,认为CRITICAL_SECTION是锁定了资源,其实,CRITICAL_SECTION是不能够“锁定”资源的,它能够完成的功能,是同步不同线程的代码段。简单说,当一个线程执行了EnterCritialSection之后,cs里面的信息便被修改了,以指明哪一个线程占用了它。而此时,并没有任何资源被“锁定”。不管什么资源,其它线程都还是可以访问的(当然,执行的结果可能是错误的)。只不过,在这个线程尚未执行LeaveCriticalSection之前,其它线程碰到EnterCritialSection语句的话,就会处于等待状态,相当于线程被挂起了。 这种情况下,就起到了保护共享资源的作用。

使用CriticalSection只适合在CriticalSection区域内处理的事情是非常简单的,耗时非常短的(程序级别的时间),如果处理事务用的时间比较长的话,就不适合用CriticalSection这种方式来解决问题

参考:

https://blog.csdn.net/qq_25408423/article/details/80885571

https://blog.csdn.net/QWERDF10010/article/details/79657821

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值