线程锁的概念函数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. LeaveCriticalSection(&cs);//解锁 到EnterCriticalSection之间代码资源已经释放了,其他线程可以进行操作
  10. return 0;
  11. }
  12. //第二个线程
  13. UINT SecondThread(LPVOID lParam)
  14. {
  15. EnterCriticalSection(&cs);//加锁
  16. for(int i = 0; i<10; i++){
  17. n_AddValue ++;
  18. cout << "n_AddValue in SecondThread is "<<n_AddValue <<endl;
  19. }
  20. LeaveCriticalSection(&cs);//解锁
  21. return 0;
  22. }

在主函数添加以下代码

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

输出:

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

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

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学习(24)线程锁的概念函数EnterCriticalSection和LeaveCriticalSection的用法相关推荐

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

    线程锁的概念函数EnterCriticalSection和LeaveCriticalSection的用法 注:使用结构CRITICAL_SECTION 需加入头文件#include "afx ...

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

    1.加入头文件 #include "afxmt.h" 2.定义一个全局的锁 CRITICAL_SECTION  的实例和一个静态变量 CRITICAL_SECTION cs;   ...

  3. 线程锁EnterCriticalSection和LeaveCriticalSection的用法

    线程锁的概念函数EnterCriticalSection和LeaveCriticalSection的用法 注:使用结构CRITICAL_SECTION 需加入头文件#include "afx ...

  4. Linux多线程(线程互斥与线程锁)

    文章目录 一.基本概念 二.互斥与同步 三.线程安全问题的底层原因 (1)抢票逻辑 (2)底层原理 四.线程锁 1.锁的使用 (1)初始化和销毁 (2)加锁和解锁 2.抢票逻辑 3.锁的原理 五.死锁 ...

  5. EnterCriticalSection和LeaveCriticalSection函数

    多个线程操作相同的数据时,一般是需要按顺序访问的,否则会引导数据错乱,无法控制数据,变成随机变量.为解决这个问题,就需要引入互斥变量,让每个线程都按顺序地访问变量.这样就需要使用EnterCritic ...

  6. VC++中多线程学习(MFC多线程)一(线程的创建、线程函数如何调用类成员呢?如何调用主对话框的成员?、MFC中的工作线程和界面线程的区别)

    这里废话不多讲了,因为项目原因,需要开启线程进行处理,在不了解线程的情况下,直接百度一下,然后就使用了,结果可想而知,出现了异常,所以花了一天时间系统学习一下多线程,这里主要是针对win32编程方面的 ...

  7. 【牛客网C++服务器项目学习】Day8-线程相关、线程锁、条件变量、信号量

    项目学习地址:[牛客网C++服务器项目学习] day08 函数:void pthread_exit(void *retval); 功能:终止调用这个函数的线程.如果是一个进程的最后一个线程调用该函数, ...

  8. [C/C++]_[初级]_[ 线程pthread学习之互斥锁和条件变量的应用 ]

    一.互斥锁 互斥锁,是一种信号量,常用来防止两个进程或线程在同一时刻访问相同的共享资源. 需要的头文件:pthread.h 互斥锁标识符:pthread_mutex_t (1)互斥锁初始化: 函数原型 ...

  9. c语言注释语句执行吗,C语言学习笔记之C语言概念解析(附资料分享)每一个语句都必须以分号结尾但预处理命令函数头和花括号“}”之后不能加分号...

    [[怪兽爱C语言]C语言学习笔记之C语言概念解析(附资料分享)]https://toutiao.com/group/6582429294901854728/?iid=15906422033&a ...

最新文章

  1. GMIS 2017大会Saman Farid演讲:人工智能时代创业者面对的挑战和机会
  2. 1、spring的IOC
  3. 迪普工业以太网交换机产品线
  4. 第一次能够在电影开场前20分钟到的经历:感谢滴答清单
  5. Thread的join方法使用解析
  6. 牛客题霸 [ 排序] C++题解/答案
  7. 华强北耳机版本太多,不知道如何选购?
  8. jmeter语言设置
  9. 路由重发分之RIP-OSPF
  10. android 好用的工具,android studio 的几个好用的工具
  11. 计算机二级费用报表,全国计算机二级ACESS 报表.doc
  12. Mysql约束 笔记
  13. R count函数_【函数分享】PHP函数str_word_count()分享(202098)
  14. C语言/C++程序必须从main函数开始吗?main函数执行完后还执行其他语句吗?
  15. SPDY, WebSocket, WebDAV概念
  16. 51单片机实验 7段数码管静态显示数字
  17. 程序员学linux意义,对于程序员而言是否需要学习Linux?有需要学些什么?
  18. UML时序图速查——架构设计必备技能
  19. 微信开发者工具官方版
  20. 图说卡尔曼滤波(C++实现)

热门文章

  1. 《诗经·小雅·小旻》
  2. 关于向已有的excel表单写入数据
  3. 【优化版】(终稿)C++实现科学计算器主函数代码(含调用函数)
  4. python 快速读取图像宽高信息
  5. MySQL基础之查询数据
  6. 互联网时代 智慧农业如何借力大数据谋发展
  7. 2022-2028年全球与中国咖啡纸杯市场现状及未来发展趋势分析报告
  8. Oracle 服务名/实例名,Service_name 和Sid的区别
  9. 计算机专业有哪些学科,计算机类专业包括哪些
  10. lol不能显示聊天服务器是怎么回事,关于LOL无法连接聊天服务器的解决方法!