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

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

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

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

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

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

在主函数加入下面代码

  1. int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
  2. {
  3. ;
  4. // 初始化 MFC 并在失败时显示错误
  5. ))
  6. {
  7. // TODO: 更改错误代码以符合您的须要
  8. _tprintf(_T("错误: MFC 初始化失败/n"));
  9. ;
  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. ];//
  18. ] = pFirstThread->m_hThread;
  19. ] = pSecondThread->m_hThread;
  20. //等待线程返回
  21. ,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. ; i++){
  5. EnterCriticalSection(&cs);//加锁 锁移到for循环内部里
  6. n_AddValue ++;
  7. cout << "n_AddValue in FirstThread is "<<n_AddValue <<endl;
  8. LeaveCriticalSection(&cs);//解锁
  9. }
  10. ;
  11. }
  12. //第二个线程
  13. UINT SecondThread(LPVOID lParam)
  14. {
  15. ; i++){
  16. EnterCriticalSection(&cs);//加锁
  17. n_AddValue ++;
  18. cout << "n_AddValue in SecondThread is "<<n_AddValue <<endl;
  19. LeaveCriticalSection(&cs);//解锁
  20. }
  21. ;
  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中间的代码运行过程不会被其它线程干拢或者这么讲不同意其它线程中
的代码运行。这样能够有效防止一个全局变量在两个线程中同一时候被操作的可能性

线程锁的概念函数EnterCriticalSection和LeaveCriticalSection的使用方法的更多相关文章

  1. Python GIL、线程锁、信号量及事件

    GIL是什么? GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念.就好比C++是一套语言(语法)标准,但是可以用不同的编译器来编译成可执行代码.有名的编 ...

  2. AtomicInteger如何保证线程安全以及乐观锁/悲观锁的概念

    众所周知,JDK提供了AtomicInteger保证对数字的操作是线程安全的,线程安全我首先想到了synchronized和Lock,但是这种方式又有一个名字,叫做互斥锁,一次只能有一个持有锁的线程进 ...

  3. 第一节:《线程安全和锁Synchronized概念》

    第一节:线程安全和锁Synchronized概念 一.进程与线程的概念 (1)在传统的操作系统中,程序并不能独立运行,作为资源分配和独立运行的基本单位都是进程. 在未配置 OS 的系统中,程序的执行方 ...

  4. day9---多线程,线程锁,队列

    进程.线程 http://www.ruanyifeng.com/blog/2013/04/processes_and_threads.html 使用threading模块实现多线程编程[综述] Pyt ...

  5. java 并发性和多线程 -- 读感 (一 线程的基本概念部分)

    1.目录略览      线程的基本概念:介绍线程的优点,代价,并发编程的模型.如何创建运行java 线程.      线程间通讯的机制:竞态条件与临界区,线程安全和共享资源与不可变性.java内存模型 ...

  6. [python] 线程锁

    参考:http://blog.csdn.net/kobeyan/article/details/44039831 1. 锁的概念 在python中,存在GIL,也就是全局解释器锁,能够保证同一时刻只有 ...

  7. Python 第八篇:异常处理、Socket语法、SocketServer实现多并发、进程和线程、线程锁、GIL、Event、信号量、进程间通讯

    本节内容: 异常处理.Socket语法.SocketServer实现多并发.进程和线程.线程锁.GIL.Event.信号量.进程间通讯.生产者消费者模型.队列Queue.multiprocess实例 ...

  8. iOS 多线程之线程锁Swift-Demo示例总结

    线程锁是什么 在前面的文章中总结过多线程,总结了多线程之后,线程锁也是必须要好好总结的东西,这篇文章构思的时候可能写的东西得许多,只能挤时间一点点的慢慢的总结了,知道了线程之后要了解线程锁就得先了解一 ...

  9. python 线程/线程锁/信号量

    单线程 #常规写法 import threading import time def sayhi(num): # 定义每个线程要运行的函数 print("running on number: ...

随机推荐

  1. Substrings 第37届ACM/ICPC 杭州赛区现场赛C题(hdu 4455)

    http://acm.hdu.edu.cn/showproblem.php?pid=4455 https://icpcarchive.ecs.baylor.edu/index.php?option=c ...

  2. MFC 对话框中动态创建N级菜单以及响应事件

    创建一个基于对话框的工程,工程名为CreateMenu 为该对话框增加一个文件菜单项和测试菜单项,如下图所示   测试菜单项至少要有一个子菜单项 在对话框属性中关联该菜单 在resource.h中增加 ...

  3. Lucene.Net 2.3.1开发介绍 —— 三、索引(六)

    原文:Lucene.Net 2.3.1开发介绍 -- 三.索引(六) 2.2 Field的Boost 如果说Document的Boost是一条线,那么Field的Boost则是一个点.怎么理解这个点呢 ...

  4. 回文(manacher)

    裸manacher 我竟然写跪了………… 一个地方(偶数)没写清楚…… 我OOXOXOXOXXOXO #include<cstdio> #include<cstdlib> #i ...

  5. CentOS7/RHEL7安装Redis步骤详解

    CentOS7/RHEL7安装Redis步骤详解 CentOS7/RHEL7安装Redis还是头一次测试安装了,因为centos7升级之后与centos6有比较大的区别了,下面我们就一起来看看Cent ...

  6. C#实现树的双亲表示法

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbHVja3k1MTIyMg==/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...

  7. Java创建、重命名、删除文件和文件夹(转)

    Java的文件操作太基础,缺乏很多实用工具,比如对目录的操作,支持就非常的差了.如果你经常用Java操作文件或文件夹,你会觉得反复编写这些代码是令人沮丧的问题,而且要大量用到递归. 下面是的一个解决方 ...

  8. 浅谈OCR之Onenote 2010

    原文:浅谈OCR之Onenote 2010 上一次我们讨论了Tesseract OCR引擎的用法,作为一款老牌的OCR引擎,目前已经开源,最新版本3.0中更是加入了中文OCR功能,再加上Google的 ...

  9. java中线程中的相关知识点

    (1)守护线程必须在线程start前设置(2)守护线程在所有用户线程结束后,也会终止(3)由于(2)所有守护线程不能执行一些读写操作,原因:如果守护线程在执行读写操作时,如果用户线程结束了,守护线程的 ...

  10. ArrayBlockingQueue和LinkedBlockingQueue的区别

    ArrayBlockingQueue和LinkedBlockingQueue的区别,得出结论如下: 1. 队列中锁的实现不同 ArrayBlockingQueue实现的队列中的锁是没有分离的,即生产和 ...