当前位置:首页 > 编程开发

理解EnterCriticalSection 临界区

webgou16年前 (2011-03-16)编程开发247

保证只有一个线程访问一段代码,其它线程不能访问

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

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

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

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://www.webgou.info/?id=446

标签: windowswinows
分享给朋友:

“理解EnterCriticalSection 临界区” 的相关文章

谁之错

故事一:背景介绍:RT是一个外包公司,ZWZX是项目承接公司,YD是甲方。RT公司每天下班的时候都会接到ZWZX负责人的电话,询问一天的工作情况,然后布置任务要求晚上加班做完,RT公司的员工很无奈也很气愤因为每天 都要加班,员工们就问项目经理:“为什么天天加班赶需求,今天才提一个需求,明…

使用Nginx实现根据 IP 匹配指定 URL

 最近的一个项目,需要特定的IP访问某专题页面的时候跳转到网站首页,思考了下,直接使用NGINX实现,分享给大家。业务需求...…

黑莓C网烧号写号的原理

中国大陆:插卡 1. 传统的方式 Sim卡 插卡 电信将UIM卡 提交给你的时候,需要将UIM卡 插在一个设备上,然后将你号码在服务器上的相关信息写进 UIM 卡中 2. Sim 卡插进手机 手机读取 Sim卡上(服务器上的)信息,开机,与电信服务器交互(电话,短信,上网) 备注: 服务器的信息--…

什么是好的API设计?

以前看别人设计api或sdk时,以为是件简单而有趣的事情,刚在csdn上看到一篇文章关于这个描述的:发表于09-05 16:33| 106次阅读| 来源richardminerich| 0 条评论| 作者Richard Minerich摘要:有人言,API设计是编程工作中最难的事情。甚至有人认为至少…

NetLimiter v3.0.0.3 Beta3 - 网络流量控制软件

NetLimiter以前夜火介绍过他的 NetLimiter Pro 2.0.9.1 汉化版 ,NetLimiter可以限制系统中每个进程所使用的网络带宽,很强大,今天看到它的 NetLimiter v3.0.0.3 Beta3 版,将其发出来。...…

送给所有的共享新手

经常看到很多同行们对共享软件能否赚到钱感到困惑,虽然大家都知道的周易前辈的MP3 CD Maker创下了月入四万的记录,但这对我们大多数人来说,只是一个很遥远的梦,就好象是水中的月亮,可望不可及。这个也曾经是我投入这个行业是的目标, 虽然到目前我的收入才达到他的四分之一,但我已心滿意足了,回顾两年…

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。