线程锁的概念函数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. VC/MFC 当鼠标移到控件上时显示提示信息

    VC/MFC 当鼠标移到控件上时显示提示信息 ToolTip是Win32中一个通用控件,MFC中为其生成了一个类CToolTipCtrl,总的说来其使用方法是较简单的,下面讲一下它的一般用法和高级用法 ...

  2. centos7 opera济览器安装

    网网下rpm安装包: http://www.opera.com/computer/thanks?partner=www&par=id%3D39136%26amp;location%3D403& ...

  3. Swift - 解析XML格式数据(分别使用GDataXML和DDXML)

    在做一些应用的时候经常需要用到XML解析,比如获取Web Service数据,读取RSS新闻或者博客数据源.下面演示了两个非常方便高效的XML库在Swift里的调用方法. 假设需要被解析的XML数据文 ...

  4. 在phpmyadmin后台获取webshell方法汇总整理

    方法一: CREATE TABLE `mysql`.`xiaoma` (`xiaoma1` TEXT NOT NULL ); INSERT INTO `mysql`.`xiaoma` (`xiaoma ...

  5. Java深入解析读书笔记(一)

    1. goto,const为java的两个保留关键字,无任何应用语法.因此从不使用.   goto 使用循环标签:if,break out,here实现goto的功能. 2. 标识符:可由字母数字下划 ...

  6. timeout connect 10000 # default 10 second time out if a backend is not found

    timeout connect <timeout> timeout contimeout <timeout> (deprecated) Set the maximum time ...

  7. 使用PageHeap.EXE或GFlags.EXE检查内存越界错误

    必先利其器之一:使用PageHeap.EXE或GFlags.EXE检查内存越界错误 Article last modified on 2002-6-3 ------------------------ ...

  8. information_schema模式表介绍 processlist

    在mysql里,我们一般通过show (full)processlist查看当前连接情况,处理各种数据库问题.现在在information_schema模式下,5.5以后增加了processlist表 ...

  9. cocos2d-x-lua基础系列教程四(lua多继承)

    lua - 多继承 1,模拟伪继承 新建extend_test.lua 新建extend_test.lua setmetable(a,b) b对象是a 对象的父类 a继承于b Account = { ...

  10. QTableView 固定列宽度(鼠标拖动后,仍可固定)

    QTableView 提供一个函数: void QTableView::setColumnWidth ( int column, int width ) 用于设置column指定的列的宽度 但setC ...