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

线程锁的概念函数EnterCriticalSection和LeaveCriticalSection的用法线程锁的概念函数EnterCriticalSection和LeaveCriticalSection的用法注:使用结构CRITICAL_SECTION需加入头文件#include“afxmt.h”定义一个全局的锁CRITICAL_SECTION的实例和一个静态全局变量CRITICAL_SECTION cs;//可以理解为锁定一个资源static int n_

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

线程锁的概念函数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 = 0i<10i++){
           
  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 = 0i<10i++){
           
  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 argcTCHARargv[]TCHARenvp[])
  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 = 0i<10i++){
  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 = 0i<10i++){
       
  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中间的代码执行过程不会被其他线程干拢或者这么讲不允许其他线程中
的代码执行。这样可以有效防止一个全局变量在两个线程中同时被操作的可能性

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/191558.html原文链接:https://javaforall.net

(0)
上一篇 2026年1月29日 下午9:22
下一篇 2026年1月29日 下午10:01


相关推荐

  • Wol 网络远程唤醒技术,通过TP-LINK路由器远程一键开启电脑

    Wol 网络远程唤醒技术,通过TP-LINK路由器远程一键开启电脑文章目录Wol网络远程唤醒技术,通过TP-LINK路由器远程一键开启电脑1、远程唤醒简介2、需要以下唤醒条件3、环境和准备工作4、配置路由器,让路由器接收你的远程开机命令5、测试配置的网络是否能够正常收到开机信号6、装个teamviewer,开机自启动,实现远程开机和远程控制Wol网络远程唤醒技术,通过TP-LINK路由器远程一键开启电脑1、远程唤醒简介远程唤醒技术(WOL,Wake-…

    2022年6月2日
    95
  • asp.net里导出excel表方法汇总

    asp.net里导出excel表方法汇总

    2021年7月22日
    59
  • zabbix监控mysql各项指标

    zabbix监控mysql各项指标准备两台虚拟机zabbix-server(服务端ip:192.168.176.138)zabbix-agent(客户端ip:192.168.176.139)两台分别上传zabbix.repo到/etc/yum.repos.d下面安装前工作//关闭防火墙systemctlstopfirewalldsetenforce0//时间同步yum-yinstallntpdatentpdatepool.ntp.org服务端[root@localhost~]#yum-y

    2022年6月10日
    67
  • os.environ模块环境变量详解

    os.environ模块环境变量详解文章目录 1 os environ 详解 1 1 简介 1 2 常见 key 字段 1 3os environ get 用法 1 4 环境变量用法总结设置 修改 获取 删除 判断 1 os environ 详解在 python 中通过 os environ 可以获取有关系统的各种信息 1 1 简介通过 os environ 获取环境变量 什么是环境变量呢 环境变量是程序和操作系统之间的通信方式 有些字符不宜明文写进代码里 比如数据库密码 个人账户密码 如果写进自己本机的环境变量里 程序用的时候通

    2026年3月19日
    2
  • nfs共享使用方法

    nfs共享使用方法

    2022年3月11日
    41
  • 串口通信中的FlowControl

    串口通信中的FlowControl串口通信中需要流控FlowControl来协调A->B传送时的数据传输速率,若A->B的数据传输速率快,B还来不及处理,则B向A发送一个信号,告诉A暂停发送,此谓流控。所谓流控即保证传输双方都能正确地发送和接收数据。流控分为硬件流控和软件流控。(1)硬件流控  DTR(第4引脚),RTS(第7引脚)计算机上的RS-232端  DSR…

    2022年6月3日
    45

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号