首页 > 代码库 > 015 临界区

015 临界区

 

  ●  EnterCriticalSection()

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

    WINBASEAPI
    VOID
    WINAPI
  EnterCriticalSection(
  __inout LPCRITICAL_SECTION lpCriticalSection
  );
  是多线程中用来确保同一时刻只有一个线程操作被保护的数据的操作函数,相关的多线程数据操作函数还有:

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

 

 1 #define UNICODE
 2 #include <stdio.h>
 3 #include <process.h>
 4 #include <windows.h>
 5 
 6 volatile int gNum;
 7 volatile int gLoopCount = 100;
 8 CRITICAL_SECTION gCs;    //临界区 -> 关键段
 9 unsigned __stdcall ThreadFunc(void* lParam)
10 {
11     static int nThreadIndex = 0;            //静态变量
12     nThreadIndex++;
13     EnterCriticalSection(&gCs);            //进去临界区
14     gNum = 0;
15     for(int i = 0; i < gLoopCount; ++i)
16     {
17         gNum += i;
18     }
19     printf("Thread%d:%d\r\n",nThreadIndex,gNum);
20     LeaveCriticalSection(&gCs);
21     return 0;
22 }
23 
24 int main()
25 {
26     const int MAXTHREADCOUNT = 10;
27     HANDLE hThreads[MAXTHREADCOUNT] = { INVALID_HANDLE_VALUE };
28     InitializeCriticalSection(&gCs);        //分配一些内存
29     InitializeCriticalSectionAndSpinCount(&gCs,1);        //以旋转锁的方式使用临界区
30     for(int i = 0; i<MAXTHREADCOUNT; ++i)
31     {
32         hThreads[i] = (HANDLE)_beginthreadex(nullptr,0,ThreadFunc,nullptr,0,nullptr);
33     }
34     WaitForMultipleObjects(MAXTHREADCOUNT, hThreads, TRUE, INFINITE);
35     for( int i = 0; i<MAXTHREADCOUNT; ++i)
36     {
37         CloseHandle(hThreads[i]);
38     }
39     DeleteCriticalSection(&gCs);
40     return 0;
41 }

技术分享

 

015 临界区