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

一、临界区临界区又称关键代码段,指的是一小段代码在代码执行前,他需要独占一些资源。程序中通常将多线程同时访问的某个资源作为临界区,需要定义一个CRITICAL_SECTION类型的变量,然后调用InitializeCriticalSection函数对变量进行初始化;函数声明:VOID InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection );lpCriticalSection:一个CRITICAL_SECTION结构指针,表示用于初始化的临界区;InitializeCriticalSection函数在内部设置了CRITICAL_SECTION结构的某些成员变量,所以他不会失败。为了将某一段代码定义为临界区,需要调用EnterCriticalSection函数;VOID WINAPI EnterCriticalSection(__inout LPCRITICAL_SECTION lpCriticalSection);该函数的作用是判断是否有线程访问临界区资源,如果没有,就改变CRITICAL_SECTION结构的成员变量的值,赋予当前线程访问权,函数立即返回;如果有线程正在访问资源,则进入等待状态,直到没有线程访问。释放资源函数:void WINAPI LeaveCriticalSection( _Inout_LPCRITICAL_SECTION lpCriticalSection);释放CRITICAL_SECTION结构指针void WINAPI DeleteCriticalSection(_Inout_ LPCRITICAL_SECTION lpCriticalSection);二、学习案例用三个线程同时运行将一个变量增加到30;临界区对象类#ifndef CAUTO_LOCK_H__#define CAUTO_LOCK_H__ class CAutoLock{public:    CAutoLock();    ~CAutoLock();     void Lock();    void UnLock(); private:    CRITICAL_SECTION m_Section;}; #endif#include "stdafx.h"#include "CAutoLock.h" CAutoLock::CAutoLock(){    InitializeCriticalSection(&m_Section);    //Lock();如果是用的时候只定义锁对象,可以不手动进入临界区和退出临界区} CAutoLock::~CAutoLock(){    DeleteCriticalSection(&m_Section);    //UnLock();} void CAutoLock::Lock(){    EnterCriticalSection(&m_Section);} void CAutoLock::UnLock(){    LeaveCriticalSection(&m_Section);}三个线程创建类#ifndef _TEST_CRITICAL_SECTION_H__#define _TEST_CRITICAL_SECTION_H__#include "CAutoLock.h"class TestCriticalSection{public:    TestCriticalSection();    ~TestCriticalSection();     void StartThread();//开始线程函数         static DWORD __stdcall ThreadFun1(LPVOID lParam);//线程回调函数1    static DWORD __stdcall ThreadFun2(LPVOID lParam);//线程回调函数2    static DWORD __stdcall ThreadFun3(LPVOID lParam);//线程回调函数3 private:    HANDLE m_hThread1;        HANDLE m_hThread2;    HANDLE m_hThread3;     CAutoLock m_lock;//三个线程公用的临界区锁     static int m_nTotals;}; #endif#include "stdafx.h"#include "CCriticalSection.h"#include <iostream>using namespace std; int TestCriticalSection::m_nTotals = 0;//初始化静态成员变量 TestCriticalSection::TestCriticalSection(){    m_nTotals = 0;        m_hThread1 = INVALID_HANDLE_VALUE;    m_hThread2 = INVALID_HANDLE_VALUE;} TestCriticalSection::~TestCriticalSection(){    if (m_hThread1 != NULL)    {        CloseHandle(m_hThread1);        m_hThread1 = NULL;    }     if (m_hThread2 != NULL)    {        CloseHandle(m_hThread2);        m_hThread2 = NULL;    }     if (m_hThread3 != NULL)    {        CloseHandle(m_hThread3);        m_hThread3 = NULL;    }} DWORD __stdcall TestCriticalSection::ThreadFun1(LPVOID lParam) //static只需要加在类定义里,类定义外面的函数定义前不能写static{    DWORD dRet = TRUE;    TestCriticalSection * pThis = static_cast<TestCriticalSection*>(lParam);    while(1)    {        pThis->m_lock.Lock();        pThis->m_nTotals ++;        cout<<"ThreadFun1: m_nTotals "<<pThis->m_nTotals<<endl;        pThis->m_lock.UnLock();        Sleep(10);        if (pThis->m_nTotals == 30)        {            break;        }    }     return dRet;} DWORD __stdcall TestCriticalSection::ThreadFun2(LPVOID lParam){    DWORD dRet = TRUE;    TestCriticalSection * pThis = static_cast<TestCriticalSection*>(lParam);    while(1)    {        pThis->m_lock.Lock();        pThis->m_nTotals ++;        cout<<"ThreadFun2: m_nTotals "<<pThis->m_nTotals<<endl;        pThis->m_lock.UnLock();        Sleep(10);        if (pThis->m_nTotals == 30)        {            break;        }    }    return dRet;} DWORD __stdcall TestCriticalSection::ThreadFun3(LPVOID lParam){    DWORD dRet = TRUE;    TestCriticalSection * pThis = static_cast<TestCriticalSection*>(lParam);    while(1)    {        pThis->m_lock.Lock();        pThis->m_nTotals ++;        cout<<"ThreadFun3: m_nTotals "<<pThis->m_nTotals<<endl;        pThis->m_lock.UnLock();        Sleep(10);        if (pThis->m_nTotals == 30)        {            break;        }    }     return dRet;} void TestCriticalSection::StartThread(){    m_hThread1 = CreateThread(NULL, 0, &TestCriticalSection::ThreadFun1, this,  0, NULL);    m_hThread2 = CreateThread(NULL, 0, &TestCriticalSection::ThreadFun2, this, 0, NULL);    m_hThread3 = CreateThread(NULL, 0, &TestCriticalSection::ThreadFun3, this, 0, NULL);}主函数:// CriticalSection.cpp : 定义控制台应用程序的入口点。// #include "stdafx.h"#include "CCriticalSection.h" int _tmain(int argc, _TCHAR* argv[]){    TestCriticalSection  CriticalSectionObj;    CriticalSectionObj.StartThread();    Sleep(5000);    system("pause");    return 0;} 结果:如果代码改成下面这样,不加临界区;资源访问会冲突#include "stdafx.h"#include "CCriticalSection.h"#include <iostream>using namespace std; int TestCriticalSection::m_nTotals = 0; TestCriticalSection::TestCriticalSection(){    m_nTotals = 0;    m_hThread1 = INVALID_HANDLE_VALUE;    m_hThread2 = INVALID_HANDLE_VALUE;} TestCriticalSection::~TestCriticalSection(){    if (m_hThread1 != NULL)    {        CloseHandle(m_hThread1);        m_hThread1 = NULL;    }     if (m_hThread2 != NULL)    {        CloseHandle(m_hThread2);        m_hThread2 = NULL;    }     if (m_hThread3 != NULL)    {        CloseHandle(m_hThread3);        m_hThread3 = NULL;    }} DWORD __stdcall TestCriticalSection::ThreadFun1(LPVOID lParam) //static只需要加在类定义里,类定义外面的函数定义前不能写static{    DWORD dRet = TRUE;    TestCriticalSection * pThis = static_cast<TestCriticalSection*>(lParam);    while(1)    {        //pThis->m_lock.Lock();        pThis->m_nTotals ++;        cout<<"ThreadFun1: m_nTotals "<<pThis->m_nTotals<<endl;        //pThis->m_lock.UnLock();        Sleep(10);        if (pThis->m_nTotals == 30)        {            break;        }    }     return dRet;} DWORD __stdcall TestCriticalSection::ThreadFun2(LPVOID lParam){    DWORD dRet = TRUE;    TestCriticalSection * pThis = static_cast<TestCriticalSection*>(lParam);    while(1)    {        //pThis->m_lock.Lock();        pThis->m_nTotals ++;        cout<<"ThreadFun2: m_nTotals "<<pThis->m_nTotals<<endl;        //pThis->m_lock.UnLock();        Sleep(10);        if (pThis->m_nTotals == 30)        {            break;        }    }    return dRet;} DWORD __stdcall TestCriticalSection::ThreadFun3(LPVOID lParam){    DWORD dRet = TRUE;    TestCriticalSection * pThis = static_cast<TestCriticalSection*>(lParam);    while(1)    {        //pThis->m_lock.Lock();        pThis->m_nTotals ++;        cout<<"ThreadFun3: m_nTotals "<<pThis->m_nTotals<<endl;        //pThis->m_lock.UnLock();        Sleep(10);        if (pThis->m_nTotals == 30)        {            break;        }    }     return dRet;} void TestCriticalSection::StartThread(){    m_hThread1 = CreateThread(NULL, 0, &TestCriticalSection::ThreadFun1, this,  0, NULL);    m_hThread2 = CreateThread(NULL, 0, &TestCriticalSection::ThreadFun2, this, 0, NULL);    m_hThread3 = CreateThread(NULL, 0, &TestCriticalSection::ThreadFun3, this, 0, NULL);}结果可能会出现下面这种状况

原文:https://blog.csdn.net/qwerdf10010/article/details/79657821 
 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值