zoukankan      html  css  js  c++  java
  • 线程锁的概念函数EnterCriticalSection和LeaveCriticalSection的使用方法

    线程锁的概念函数EnterCriticalSection和LeaveCriticalSection的使用方法

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

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

    1. CRITICAL_SECTION cs;//能够理解为锁定一个资源
    2. static int n_AddValue = 0;//定义一个静态的所有变量n_AddValue

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

    1. //第一个线程
    2. UINT FirstThread(LPVOID lParam)
    3. {
    4.     EnterCriticalSection(&cs);//加锁 接下来的代码处理过程中不同意其它线程进行操作,除非遇到LeaveCriticalSection
    5.     for(int i = 0; i<10; i++){       
    6.         n_AddValue ++;
    7.         cout << "n_AddValue in FirstThread is "<<n_AddValue <<endl;       
    8.    
    9.     }
    10.     LeaveCriticalSection(&cs);//解锁 到EnterCriticalSection之间代码资源已经释放了,其它线程能够进行操作   
    11.     return 0;
    12.  
    13. }
    14.  
    15. //第二个线程
    16. UINT SecondThread(LPVOID lParam)
    17. {
    18.     EnterCriticalSection(&cs);//加锁
    19.     for(int i = 0; i<10; i++){       
    20.         n_AddValue ++;       
    21.         cout << "n_AddValue in SecondThread is "<<n_AddValue <<endl;   
    22.        
    23.     }
    24.     LeaveCriticalSection(&cs);//解锁
    25.  
    26.     return 0;
    27.  
    28. }

    在主函数加入下面代码

    1. int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
    2. {
    3.     int nRetCode = 0;
    4.  
    5.     // 初始化 MFC 并在失败时显示错误
    6.     if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
    7.     {
    8.         // TODO: 更改错误代码以符合您的须要
    9.         _tprintf(_T("错误: MFC 初始化失败/n"));
    10.         nRetCode = 1;
    11.     }
    12.     else
    13.     {
    14.  
    15.         InitializeCriticalSection(&cs);//初始化结构CRITICAL_SECTION
    16.  
    17.  
    18.         CWinThread *pFirstThread,*pSecondThread;//存储函数AfxBeginThread返回的CWinThread指针
    19.        
    20.  
    21.         pFirstThread  = AfxBeginThread(FirstThread,LPVOID(NULL));//启动第一个线程
    22.         pSecondThread = AfxBeginThread(SecondThread,LPVOID(NULL));//启动第二个线程
    23.  
    24.         HANDLE hThreadHandle[2];//
    25.         hThreadHandle[0] = pFirstThread->m_hThread;
    26.         hThreadHandle[1] = pSecondThread->m_hThread;
    27.  
    28.         //等待线程返回
    29.         WaitForMultipleObjects(2,hThreadHandle,TRUE,INFINITE);       
    30.     }
    31.  
    32.     return nRetCode;
    33. }

    输出:

    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循环中去,线程的运行顺序将会改变
    输出也就跟着改变,如:

    1. //第一个线程
    2. UINT FirstThread(LPVOID lParam)
    3. {
    4.    
    5.     for(int i = 0; i<10; i++){
    6.         EnterCriticalSection(&cs);//加锁 锁移到for循环内部里
    7.         n_AddValue ++;
    8.         cout << "n_AddValue in FirstThread is "<<n_AddValue <<endl;   
    9.         LeaveCriticalSection(&cs);//解锁 
    10.     }   
    11.     return 0;
    12. }
    13.  
    14. //第二个线程
    15. UINT SecondThread(LPVOID lParam)
    16. {
    17.    
    18.     for(int i = 0; i<10; i++){   
    19.         EnterCriticalSection(&cs);//加锁
    20.         n_AddValue ++;       
    21.         cout << "n_AddValue in SecondThread is "<<n_AddValue <<endl;
    22.         LeaveCriticalSection(&cs);//解锁       
    23.     }
    24.     return 0;
    25. }

    其它代码不变,输出的结果例如以下:

    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中间的代码运行过程不会被其它线程干拢或者这么讲不同意其它线程中
    的代码运行。这样能够有效防止一个全局变量在两个线程中同一时候被操作的可能性

  • 相关阅读:
    python连接redis
    python3进行md5加密
    python操作mysql数据库
    python3操作excle
    memcache与redis的存储类型
    模块
    函数
    json与字典相互转换
    常用的Random函数
    字符串常用方法
  • 原文地址:https://www.cnblogs.com/blfshiye/p/4548872.html
Copyright © 2011-2022 走看看