critical临界的,EnterCriticalSection

  critical临界的,EnterCriticalSection

  通俗的解释就像上厕所:

  门是锁着的,就等着,等别人出来了,进去锁上,然后做你该做的,做完了就开门。

  如果门没锁,就进去,锁上,然后做你想做的事。完事后,打开门。

  -

  多线程用于确保同一时间只有一个线程操作受保护的数据。

  InitializeCriticalSection(cs);//初始化临界区

  enter critical section(cs);//进入临界区

  //运行数据

  MyMoney *=10//所有访问MyMoney变量的程序都需要写Enter.像这样离开。

  LeaveCriticalSection(cs);//离开临界区

  DeleteCriticalSection(cs);//删除关键部分

  多线程操作同一数据时,一般需要按顺序访问,否则会导致数据无序、数据不可控、随机变量。为了解决这个问题,我们需要引入互斥变量,这样每个线程都可以顺序访问变量。这样,您需要使用EnterCriticalSection和LeaveCriticalSection函数。

  比如我们定义一个共享资源dwTime[100],线程ThreadFuncA和ThreadFuncB都对其进行读写。当我们想要保证dwTime[100]的操作完整性,也就是不希望写入的数据有一半被另一个线程读取,那么我们使用CRITICAL_SECTION进行线程同步,如下所示:

  第一个线程函数:

  DWORD WINAPI thread funca(LPVOID LP)

  {

  enter critical section(cs);

  .

  //运行dwTime

  .

  LeaveCriticalSection(cs);

  返回0;

  }

  写了这个函数后,很多初学者会误以为此时cs已经锁定了dwTime,dwTime处于cs的保护之下。一个“自然”的想法是——cs和dwTime一一对应。

  这样想就大错特错了。DW不对应任何东西,它仍然可以被任何其他线程访问。如果你按如下方式编写第二个线程,那么就会出现问题:

  DWORD WINAPI thread funcb(LPVOID LP)

  {

  .

  //运行dwTime

  .

  返回0;

  }

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

  为了使CRITICAL_SECTION工作,我们必须在访问dwTime的任何地方添加语句EnterCriticalSection( cs)和LeaveCriticalSection( cs)。因此,第二个线程函数必须编写如下:

  DWORD WINAPI thread funcb(LPVOID LP)

  {

  enter critical section(cs);

  .

  //运行dwTime

  .

  LeaveCriticalSection(cs);

  返回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,依此类推。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: