孙鑫 第十五/十六课之四 线程同步CriticalSection

说明

临界区,类似互斥对象Mutex,用起来比较简单,速度快,是比较推荐的一种。

一般步骤:

初始化一个临界区(新建一个电话亭,只能容纳一个人)

等待进入临界区(等待进入电话亭,进入后上锁别人继续等待,如果多次上锁则要多次开锁)

离开临界区(离开电话亭要开锁,以便让其他人进入,有几道锁开几道锁,如果不开锁则别人不能进入)

删除临界区(城管把电话亭拆了)


 

1 初始化

VOID InitializeCriticalSection(

LPCRITICAL_SECTION   lpCriticalSection  //[out]  CRITICAL_SECTION结构体指针,实际是struct  _RTL_CRITICAL_SECTION类型。

);

初始化一个临界区,相当于新建一个电话亭。

eg.

CRITICAL_SECTION  criticalSection;

InitializeCriticalSection(&criticalSection);

 

 

2 进入临界区

VOID  EnterCriticalSection(

LPCRITICAL_SECTION   lpCriticalSection  // [in / out]

);

eg.

EnterCriticalSection(&criticalSection);  //进入临界区,加锁,如果多次加锁则要有多次开锁

 

 

3 离开临界区

VOID  LeaveCriticalSection(

LPCRITICAL_SECTION   lpCriticalSection  // [in / out]

);

eg.

LeaveCriticalSection(&criticalSection); //离开临界区,开锁,有几道锁开几道锁

 

4 删除临界区

VOID  DeleteCriticalSection(

LPCRITICAL_SECTION   lpCriticalSection  // [in / out]

);

删除临界区,前提是临界区必须已经用InitializeCriticalSection函数创建

eg.

DeleteCriticalSection(&criticalSection);

 

 

5 实例

两个子线程分别给两个编辑框赋值,用临界区保证他们不同时更新


/74CriticalSectionDlg.h  类声明///

public:

    static UINT MyThread1(LPVOID lpParam);

    static UINT MyThread2(LPVOID lpParam);

 

private:

    static CRITICAL_SECTION m_criticalSection;

     

/74CriticalSectionDlg.cpp  类定义/

 

//初始化静态成员变量,该变量为结构体,静态成员变量作为结构体的初始化采用类似形式!

CRITICAL_SECTION CMy74CriticalSectionDlg::m_criticalSection = {0};

 

//对话框初始化

BOOL CMy74CriticalSectionDlg::OnInitDialog()

{

    //codes

    InitializeCriticalSection(&m_criticalSection);  //初始化临界区

    CWinThread* pThread1 = AfxBeginThread(MyThread1, (LPVOID)&m_ctrlEdit1);  //开启两个线程

    CWinThread* pThread2 = AfxBeginThread(MyThread2, (LPVOID)&m_ctrlEdit2);

    //codes

}

 

 

//子线程1

UINT CMy74CriticalSectionDlg::MyThread1(LPVOID lpParam)

{

    CString str;

    int a = 0;

    CEdit* pEdit = (CEdit*)lpParam;

 

    while (true)

    {

        EnterCriticalSection(&m_criticalSection); //等待进入临界区,进入后加锁使其他线程不能进入

        str.Format("%d", ++a);

        str += "  a";

        pEdit->SetWindowText(str);

        Sleep(100);

        if (a >= 1000)

        {

            LeaveCriticalSection(&m_criticalSection);  //当a>=1000时线程1退出,如果不加此句则线程2永远不能进入临界区

            break;

        }

        LeaveCriticalSection(&m_criticalSection);  //离开 开锁

    }

    return 0;

}

 

 

//子线程2

UINT CMy74CriticalSectionDlg::MyThread2(LPVOID lpParam)

{

    CString str;

    int b = 0;

    CEdit* pEdit = (CEdit*)lpParam;

 

    while (true)

    {

        EnterCriticalSection(&m_criticalSection);//等待进入临界区,进入后加锁

        str.Format("%d", ++b);

        str += "  b";

        pEdit->SetWindowText(str);

        Sleep(100);

        LeaveCriticalSection(&m_criticalSection); //离开 开锁

    }

    return 0;

}

 

NOTE:如果子线程1或2中调用了多次EnterCriticalSection,在线程退出或一次循环结束时也要调用多次LeaveCriticalSection。


 孙鑫 第十五/十六课之四  线程同步CriticalSection - 大灰狼 - 大灰狼 的博客



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值