一般的解释就像上厕所一样:
门锁好了,等一下,等别人出来,进去锁门,然后该做什么,结束后,请开门
如果门上没有钥匙,就进去,锁门,然后该做什么,结束后开门。
请参见—————————————– –
多线程允许在同一时刻只有一个线程处理受保护的数据
初始化身份验证(cs ); //初始化极限区域
企业安全(cs ); //进入临界区
//操作数据
MyMoney*=10; 访问MyMoney变量的所有程序都必须这样写Enter. Leave .
leavecriticalsection(cs; //离开临界区
删除安全性(cs ); //删除关键部分
当多个线程处理同一数据时,通常需要按顺序访问。 否则,数据会错乱,无法控制数据,成为随机变量。 要解决此问题,必须引入互斥变量,以允许每个线程按顺序访问变量。 为此,必须使用EnterCriticalSection函数和LeaveCriticalSection函数。
例如,定义共享资源dwTime[100],两个线程ThreadFuncA和ThreadFuncB进行读写。 如果要确保dwTime[100]操作的完整性,也就是说,如果不希望另一个线程读取写入一半的数据,则使用CRITICAL_SECTION同步线程将如下所示:
第一个线程函数:
dwordwinapithreadfunca (lpvoid LP ) )。
{
企业安全(cs );
.
//操作dwTime
.
leavecriticalsection(cs;
返回0;
}
写这个函数的话,很多初学者会认为此时cs锁定操作dwTime,dwTime在cs的保护下。 一种“自然”的想法是——cs和dwTime一一对应。
这样想的话,就大错特错了。 dwTime不支持任何内容,也可以由其他线程访问。 如果写下第二个线程,就有问题了。
dwordwinapithreadfuncb (lpvoid LP ) )。
{
.
//操作dwTime
.
返回0;
}
当线程ThreadFuncA运行EnterCriticalSection(cs )并开始执行dwTime[100]操作时,线程ThreadFuncB随时都可能醒来,并且dwTime[100]操作也可能开始以这种方式,dwTime[100]
为了使CRITICAL_SECTION发挥作用,必须在访问dwTime的任何地方添加entercriticalsection(cs )和leavecriticalsection (cs )语句。 因此,第二个线程函数必须写为:
dwordwinapithreadfuncb (lpvoid LP ) )。
{
企业安全(cs );
.
//操作dwTime
.
leavecriticalsection(cs;
返回0;
}
这样,当线程ThreadFuncB醒来时,遇到的第一个语句是entercriticalsection(cs ),该语句访问cs变量。 如果此时第一个线程仍在操作dwTime[100],则cs变量中包含的值会通知第二个线程其他线程已经占用了cs。 因此,不返回第二个线程的entercriticalsection(cs )语句,而是进入挂起状态。 第二个线程的entercriticalsection (cs )语句将返回并继续执行以下操作,直到第一个线程执行leavecriticalsection(cs ) :
该过程实际上是通过限制CriticalSection变量只包含一个函数来实现代码段同步。 简单地说,如果对于同一个CRITICAL_SECTION,某个线程运行了EnterCriticalSection,但没有运行LeaveCriticalSection,则没有其他线程运行entercriticalssection
我再强调一次。 资源未被“锁定”。 CRITICAL_SECTION这个东东不是为了资源,而是为了不同线程之间的代码段。 可以使用它“锁定”资源,方法是将EnterCriticalSection和LeaveCriticalSection语句添加到访问共享资源的所有位置,同时只有一个线程的代码段可以锁定共享资源
这是使用一个CRITICAL_SECTION的情况。 要知道,没有任何可以同步的资源“集合”。 这个概念不正确。
对于两个CRITICAL_SECTION,将会出现以下情况: