理解EnterCriticalSection 临界区

通俗解释就像上厕所:
门锁了,就等着,等到别人出来了,进去锁上,然后该干什么干什么,干完了,把门打开

门没锁,就进去,锁上,然后该干什么干什么,干完了,把门打开

--------------------------------------------------
多线程中用来确保同一时刻只有一个线程操作被保护的数据

InitializeCriticalSection(&cs);//初始化临界区
EnterCriticalSection(&cs);//进入临界区
//操作数据
MyMoney*=10;//所有访问MyMoney变量的程序都需要这样写Enter.. Leave...
LeaveCriticalSection(&cs);//离开临界区
DeleteCriticalSection(&cs);//删除临界区

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

 

比如说我们定义了一个共享资源dwTime[100],两个线程ThreadFuncA和ThreadFuncB都对它进行读写操作。当我们想要保证 dwTime[100]的操作完整性,即不希望写到一半的数据被另一个线程读取,那么用CRITICAL_SECTION来进行线程同步如下:

第一个线程函数:

DWORD   WINAPI   ThreadFuncA(LPVOID   lp)
{
EnterCriticalSection(&cs);
...
//   操作dwTime
...
LeaveCriticalSection(&cs);
return   0;
}

写出这个函数之后,很多初学者都会错误地以为,此时cs对dwTime进行了锁定操作,dwTime处于cs的保护之中。一个“自然而然”的想法就是——cs和dwTime一一对应上了。

这么想,就大错特错了。dwTime并没有和任何东西对应,它仍然是任何其它线程都可以访问的。如果你像如下的方式来写第二个线程,那么就会有问题:

DWORD   WINAPI   ThreadFuncB(LPVOID   lp)
{
...
//   操作dwTime
...
return   0;
}

当线程ThreadFuncA执行了EnterCriticalSection(&cs),并开始操作dwTime[100]的时候,线程 ThreadFuncB可能随时醒过来,也开始操作dwTime[100],这样,dwTime[100]中的数据就被破坏了。

为了让CRITICAL_SECTION发挥作用,我们必须在访问dwTime的任何一个地方都加上 EnterCriticalSection(&cs)和LeaveCriticalSection(&cs)语句。所以,必须按照下面的 方式来写第二个线程函数:

DWORD   WINAPI   ThreadFuncB(LPVOID   lp)
{
EnterCriticalSection(&cs);
...
//   操作dwTime
...
LeaveCriticalSection(&cs);
return   0;
}

这样,当线程ThreadFuncB醒过来时,它遇到的第一个语句是EnterCriticalSection(&cs),这个语句将对cs变量 进行访问。如果这个时候第一个线程仍然在操作dwTime[100],cs变量中包含的值将告诉第二个线程,已有其它线程占用了cs。因此,第二个线程的 EnterCriticalSection(&cs)语句将不会返回,而处于挂起等待状态。直到第一个线程执行了 LeaveCriticalSection(&cs),第二个线程的EnterCriticalSection(&cs)语句才会返回, 并且继续执行下面的操作。

这个过程实际上是通过限制有且只有一个函数进入CriticalSection变量来实现代码段同步的。简单地说,对于同一个 CRITICAL_SECTION,当一个线程执行了EnterCriticalSection而没有执行LeaveCriticalSection的时 候,其它任何一个线程都无法完全执行EnterCriticalSection而不得不处于等待状态。

再次强调一次,没有任何资源被“锁定”,CRITICAL_SECTION这个东东不是针对于资源的,而是针对于不同线程间的代码段的!我们能够用它来进 行所谓资源的“锁定”,其实是因为我们在任何访问共享资源的地方都加入了EnterCriticalSection和 LeaveCriticalSection语句,使得同一时间只能够有一个线程的代码段访问到该共享资源而已(其它想访问该资源的代码段不得不等待)。

这就是使用一个CRITICAL_SECTION时的情况。你应该要知道,它并没有什么可以同步的资源的“集合”。这个概念不正确。

如果是两个CRITICAL_SECTION,就以此类推。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/452743.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python多线程--UDP聊天器

import socket import threadingdef recv_msg(udp_socket):"""接收数据并显示"""# 接收数据while True:recv_data udp_socket.recvfrom(1024)print(recv_data)def send_msg(udp_socket, dest_ip, dest_port):"""发送数据"&…

mvc:default-servlet-handler/作用

<mvc:default-servlet-handler/>使用默认的servlet来相应静态文件&#xff0c;因为在web.xml中使用了DispatcherServlet截获所有的请求url&#xff0c;而引入<scprit type"text/javascript" src"js/jquery-1.11.0.mim.js"/>的时候&#xff0c;…

java中如何做模糊查询_到底Java里的模糊查询语句该怎么写

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼现在String sql"select * from car where carName like %?%";可以查询出结果了&#xff0c;但问题又来了&#xff0c;只能查询出一条结果&#xff0c;代码如下carDao.java页面public ArrayList queryAppoint(String car…

vector 、map 、iterator 之学习笔记

由于本人要接手一项C方面 的工作。由于不会C,不过做过JAVA 以及一些web方面的开发&#xff0c;加之时间比较短。所以需要速成&#xff0c;于是学习笔记也基本都是用代码代替。 //范例资源文件 /****************************************************************************…

redis的密码验证,及哨兵的相关配置

背景我们知道&#xff0c;redis默认是不配置密码的&#xff0c;这就造成只要有redis的IPPort就可以无需验证&#xff0c;登陆redis。如果恰巧你的redis是开放在公网上的&#xff0c;很容易就被******&#xff0c;获取你的系统权限&#xff0c;经常被黑去当成了矿机。redis的安全…

tag的使用

tag True while tag:print("level")choice input("level>>>").strip() #作用是暂停 不会一直死循环if choice "quit":break #终止当前循环进入到上一层if choice "quit_all": tag False #不用一层层退出 直接退出整个…

pyecharts对于经纬度_一文带你掌握Pyecharts地理数据可视化的方法

本文主要介绍了Pyecharts地理数据可视化&#xff0c;分享给大家&#xff0c;具体如下&#xff1a;一、Pyecharts简介和安装1. 简介Echarts 是一个由百度开源的数据可视化&#xff0c;凭借着良好的交互性&#xff0c;精巧的图表设计&#xff0c;得到了众多开发者的认可。而 Pyth…

使用Sqlmap对dvwa进行sql注入测试(初级阶段)

0.测试准备 1&#xff09;打开Kali虚拟机终端; 2&#xff09;打开靶机OWASP&#xff0c;并通过浏览器&#xff0c;输入IP地址进入dvwa的主页&#xff0c;然后选择SQL injection进入SQL注入的测试页面 1.获取DVWA的url和cookie 在输入框中输入1&#xff0c;显示有内容&…

什么是软件生命周期

软件生命周期又称为软件生存周期或系统开发生命周期&#xff0c;是软件的产生直到报废的生命周期&#xff0c;周期内有问题定义、可行性分析、总体描述、系统设计、编码、调试和测试、验收与运行、维护升级到废弃等阶段&#xff0c;这种按时间分程的思想方法是软件工程中的一种…

STL中map和string, vector 用法详解

1. map 用法详解 std map是STL的一个关联容器&#xff0c;它提供一对一&#xff08;其中第一个可以称为关键字&#xff0c;每个关键字只能在map中出现一次&#xff0c;第二个可能称为该关键字的值&#xff09;的数据处理能力&#xff0c;由于这个特性&#xff0c;它完成有可能…

如果备份还原SecureCRT、Xshell远程工具远程

因为有时候电脑操作系统要重新安装&#xff0c;需要将远程备份下来。或者要将远程发给其他同事。一、如何备份还原SecureCRT远程1、打开options-global options---general---configuration paths找到配置文件保存路径&#xff0c;如下图&#xff1a;2、打开C:\Users\NUC\AppDat…

Centos7 下yum安装mysql

转载于:https://www.cnblogs.com/nbjjy/p/9023991.html

Python协程--迭代器

0. 实现一个可以迭代的对象 1&#xff09;要想使一个对象实现迭代的功能&#xff0c;须实现__iter__和__next__方法。 2&#xff09;判断classmate是否是可以迭代的对象&#xff1a; from collections import Iterable isinstance(classmate, Iterable)结果为True则说明是可以…

什么是敏捷开发

什么是敏捷开发&#xff1f; 敏捷开发(Agile Development)是一种以人为核心、迭代、循序渐进的开发方法。 怎么理解呢&#xff1f;首先&#xff0c;我们要理解它不是一门技术&#xff0c;它是一种开发方法&#xff0c;也就是一种软件开发的流程&#xff0c;它会指导我们用规定的…

May 18:PHP 输出语句

通过前面的学习了解了php的基本语法&#xff0c;今天向大家简单介绍php的几种输出方式&#xff1a; 1. echo 常用的输出语句&#xff0c;例如&#xff1a;echo helloworld&#xff01;; 2. print() 输出语句&#xff0c;有返回值。例如&#xff1a;print(helloworld&#x…

SendMessage、PostMessage原理和源代码详解

本文讲解SendMessage、PostMessage两个函数的实现原理&#xff0c;分为三个步骤进行讲解&#xff0c;分别适合初级、中级、高级程序员进行理解&#xff0c;三个步骤分别为&#xff1a; 1、SendMessage、PostMessage的运行机制。 2、SendMessage、PostMessage的运行内幕。 3、…

Python协程--实现斐波那契数列(Fibonacci)的几种方式

1.使用for遍历list数组 # 使用for遍历list数组 nums list() a 0 b 1 i 0while i < 10:nums.append(a)a, b b, abi 1for num in nums:print(num)2.使用迭代器完成 class Fibonacci(object):def __init__(self, all_num):self.all_num all_numself.current_num 0sel…

敏捷开发宣言

敏捷开发宣言&#xff1a; 1. 个体和交互胜过过程和工具 2. 可工作的软件胜过面面俱到的文档 3. 客户协作胜过合同谈判 4. 响应变化胜过遵循计划 从上面的宣言可以看出&#xff0c;敏捷开发的核心是人 、协作、时刻可运行的软件、变化。

java fast math,Java FastMath.signum方法代码示例

import org.apache.commons.math3.util.FastMath; //导入方法依赖的package包/类/*** {inheritDoc}*/Overrideprotected double doSolve()throws TooManyEvaluationsException,NoBracketingException {double min getMin();double max getMax();// [x1, x2] is the bracketin…

什么是可行性研究

1.并非任何问题都有简单明显的解决办法&#xff0c;事实上&#xff0c;许多问题不可能在预定的系统规模或时间期限之内解决。2.如果问题没有可行的解&#xff0c;那么花费在这项工程上的任何时间、人力、软硬件资源和经费&#xff0c;都是无谓的浪费。3.可行性研究的目的&#…