critical临界的_临界区的定义

critical临界的_临界区的定义通俗解释就像上厕所:门锁了,就等着,等到别人出来了,进去锁上,然后该干什么干什么,干完了,把门打开门没锁,就进去,锁上,然后该干什么干什么,干完了,把门打开————————————————–多线程中用来确保同一时刻只有一个线程操作被保护的数据InitializeCriticalSection(&cs);//初始


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

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

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

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

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,就以此类推。

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

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

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • mysql数据库优化总结

    mysql数据库优化总结

    2021年10月15日
  • Android SDK下载和安装,以及部署「建议收藏」

    Android SDK下载和安装,以及部署「建议收藏」第一步:先到网站地址下载资源下载地址:https://www.androiddevtools.cn/第二步:选择具体版本资源下载第三步:点击启动安装SDKManager.exe选择相应的工具包进行下载对于扩展选项:这里建议全选分别选中每个License,分别设置为AcceptLicense[这样更方便快捷!!]确认好都勾选后,点击Install下载注意:下载可能比较慢,耗费时间长,最重要的是保证网络好,没下载成功,就重进重选重新下载…

    2022年7月19日
  • ViewStub的使用

    ViewStub的使用ViewStub经常用在ListView中,用来隐藏一些操作,使用起来也很简单,主要就是在ListView的Item中通过一个ViewStub来引用被隐藏的布局文件。监听用户点击Item,判断下当前是可见还是不可见,实时进行状态的转换即可。效果图如下:   下面看代码:MainActivity.java:设置数据源 publicclassMainActiv…

    2022年6月28日
  • 服务器硬件基础知识

    服务器硬件基础知识服务器的概述计算机的硬件主要有主机和输入/输出设备。主机包括机箱,电源,主板,CPU(中央处理器),内存,显卡,声卡,网卡,硬盘,光驱等。输入/输出包括显示器,键盘,鼠标,音箱,摄像头,打印机和扫描仪等。服务器服务器是指在网络环境下运行相应的应用软件,为网上用户提供共享信息资源和各种服务的一直高性能计算机。服务器的选择:处理器性能,I/O性能,管理性,可靠性,扩展性。同样…

    2022年7月22日
  • 大数据开发步骤和流程「建议收藏」

    大数据项目开发步骤:第一步:需求:数据的输入和数据的产出;第二步:数据量、处理效率、可靠性、可维护性、简洁性;第三步:数据建模;第四步:架构设计:数据怎么进来,输出怎么展示,最最重要的是处理流出数据的架构;第五步:再次思考大数据系统和企业IT系统的交互;第六步:最终确定选择、规范等;第七步:基于数据建模写基础服务代码;第八步:正式编写第一个模块;第九步:实现其它…

    2022年4月8日
  • 解决问题:jar中没有主清单属性「建议收藏」

    解决问题:jar中没有主清单属性「建议收藏」pom.xml文件中添加:<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configurat

    2022年9月5日

发表回复

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

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