您的位置:首页 > 其它

MFC学习(24)线程锁的概念函数EnterCriticalSection和LeaveCriticalSection的用法

2017-04-10 00:35 501 查看
线程锁的概念函数EnterCriticalSection和LeaveCriticalSection的用法

注:使用结构CRITICAL_SECTION 需加入头文件#include “afxmt.h”

定义一个全局的锁 CRITICAL_SECTION的实例

和一个静态全局变量

CRITICAL_SECTION cs;//可以理解为锁定一个资源

static int n_AddValue = 0;//定义一个静态的全部变量n_AddValue

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

//第一个线程
UINT FirstThread(LPVOID lParam)

{
    EnterCriticalSection(&cs);//加锁
接下来的代码处理过程中不允许其他线程进行操作,除非遇到LeaveCriticalSection
    for(int i = 0; i<10; i++){ 
     
        n_AddValue ++;

        cout << "n_AddValue in FirstThread is "<<n_AddValue <<endl; 
     
   
    }
    LeaveCriticalSection(&cs);//解锁
到EnterCriticalSection之间代码资源已经释放了,其他线程可以进行操作   
    return 0;

 
}
 
//第二个线程
UINT SecondThread(LPVOID lParam)

{
    EnterCriticalSection(&cs);//加锁

    for(int i = 0; i<10; i++){ 
     
        n_AddValue ++;       

        cout << "n_AddValue in SecondThread is "<<n_AddValue <<endl; 
 
       
    }
    LeaveCriticalSection(&cs);//解锁

 
    return 0;

 
}

在主函数添加以下代码

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])

{
    int nRetCode = 0;

 
    // 初始化 MFC 并在失败时显示错误

    if (!AfxWinInit(::GetModuleHandle(NULL), NULL,
::GetCommandLine(), 0))

    {
        // TODO: 更改错误代码以符合您的需要

        _tprintf(_T("错误: MFC 初始化失败/n"));

        nRetCode = 1;

    }
    else
    {
 
        InitializeCriticalSection(&cs);//初始化结构CRITICAL_SECTION

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

       
 
        pFirstThread  = AfxBeginThread(FirstThread,LPVOID(NULL));//启动第一个线程

        pSecondThread = AfxBeginThread(SecondThread,LPVOID(NULL));//启动第二个线程

 
        HANDLE hThreadHandle[2];//

        hThreadHandle[0] = pFirstThread->m_hThread;

        hThreadHandle[1] = pSecondThread->m_hThread;

 
        //等待线程返回

        WaitForMultipleObjects(2,hThreadHandle,TRUE,INFINITE); 
     
    }
 
    return nRetCode;

}

输出:

n_AddValue in FirstThread is 1

n_AddValue in FirstThread is 2

n_AddValue in FirstThread is 3

n_AddValue in FirstThread is 4

n_AddValue in FirstThread is 5

n_AddValue in FirstThread is 6

n_AddValue in FirstThread is 7

n_AddValue in FirstThread is 8

n_AddValue in FirstThread is 9

n_AddValue in FirstThread is 10

n_AddValue in SecondThread is 11

n_AddValue in SecondThread is 12

n_AddValue in SecondThread is 13

n_AddValue in SecondThread is 14

n_AddValue in SecondThread is 15

n_AddValue in SecondThread is 16

n_AddValue in SecondThread is 17

n_AddValue in SecondThread is 18

n_AddValue in SecondThread is 19

n_AddValue in SecondThread is 20

如果把两个线程函数中的EnterCriticalSection和LeaveCriticalSection位置移到for循环中去,线程的执行顺序将会改变

输出也就跟着改变,如:

//第一个线程
UINT FirstThread(LPVOID lParam)

{
   
    for(int i = 0; i<10; i++){

        EnterCriticalSection(&cs);//加锁
锁移到for循环内部里
        n_AddValue ++;

        cout << "n_AddValue in FirstThread is "<<n_AddValue <<endl; 
 
        LeaveCriticalSection(&cs);//解锁 

    }   

    return 0;

}
 
//第二个线程
UINT SecondThread(LPVOID lParam)

{
   
    for(int i = 0; i<10; i++){ 
 
        EnterCriticalSection(&cs);//加锁

        n_AddValue ++;       

        cout << "n_AddValue in SecondThread is "<<n_AddValue <<endl;

        LeaveCriticalSection(&cs);//解锁 
     
    }
    return 0;

}

其他代码不变,输出的结果如下:

n_AddValue in FirstThread is 1

n_AddValue in SecondThread is 2

n_AddValue in FirstThread is 3

n_AddValue in SecondThread is 4

n_AddValue in FirstThread is 5

n_AddValue in SecondThread is 6

n_AddValue in FirstThread is 7

n_AddValue in SecondThread is 8

n_AddValue in FirstThread is 9

n_AddValue in SecondThread is 10

n_AddValue in FirstThread is 11

n_AddValue in SecondThread is 12

n_AddValue in FirstThread is 13

n_AddValue in SecondThread is 14

n_AddValue in FirstThread is 15

n_AddValue in SecondThread is 16

n_AddValue in FirstThread is 17

n_AddValue in SecondThread is 18

n_AddValue in FirstThread is 19

n_AddValue in SecondThread is 20

个人认为在函数EnterCriticalSection和LeaveCriticalSection中间的代码执行过程不会被其他线程干拢或者这么讲不允许其他线程中

的代码执行。这样可以有效防止一个全局变量在两个线程中同时被操作的可能性

 

该文章转载至:http://blog.csdn.net/luoyouren/article/details/50548790
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  mfc 线程
相关文章推荐