线程同步——用户模式下线程同步——关键段实现线程同步

 1  //2.使用关键段实现线程同步
 2  使用时必须有以下几个步骤  3  //(1)必须先定义 CRITICAL_SECTION 结构
 4  CRITICAL_SECTION g_cs;  5  //(2)初始化关键段 CRITICAL_SECTION
 6  InitializeCriticalSection(&g_cs);  7  //(3)在线程中调用
 8  DWORD WINAPI ThreadFunOne(PVOID pvParam)  9  { 10      EnterCriticalSection(&g_cs) ; 11 
12      //共享的资源应该放在EnterCriticalSection和EnterCriticalSection函数之间
13 
14      EnterCriticalSection(&g_cs); 15      return 0; 16  } 17  //(4)清理CRITICAL_SECTION结构,必须确保已经没有资源使用此关键段,否则会出现不可预料的结果
18  DeleteCriticalSection(&g_cs); 19 //关于
20 VOID EnterCriticalSection( LPCRITICAL_SECTION lpCriticalSection ) ; 21 1)如果没有线程正在访问资源,那么EnterCriticalSection立刻更新成员变量,以表示调用线程 22  已经获准的对资源的访问,并立即返回,这样线程可以继续执行代码(访问资源)。 23     2)如果成员变量表示调用线程已经获准访问资源,那么EnterCriticalSection更新变量,以表示调用线程被准获访问次数, 24  并立即返回。这种情况很少,只有当线程调用LeaveCriticalSection 之前连续调用EnterCriticalSection两次及以上才会发生。 25     3)如果成员变量表示有一个(调用线程之外的其他)线程已经获准访问资源,那么EnterCriticalSection会使用 26  一组内核对象,把线程切换为等待状态,等待不会浪费CPU时间,这就完美了。 27  一句话概括就是:调用 EnterCriticalSection 一个线处理资源,其他线程变为等待。 28 
29  VOID LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection ) 30  系统会自动更新 CRITICAL_SECTION 的成员变量并将等待的线程,切换为可调度状态。 31 
32 
33  VOID TryEnterCriticalSection( LPCRITICAL_SECTION lpCriticalSection ) ; 34 此函数可以代替 EnterCriticalSection 函数,但是: 35  此函数从来不会让调用线程等待。它可以通过返回值查看,调用线程是否获准访问资源, 36  如果其它线程正在访问资源,则返回 FALSE ,否则,返回 TRUE 。 37 
38 
39 #include "windows.h"
40 #include "iostream"
41 using namespace std; 42 long g_x = 0 ; 43 //(1)必须先定义 CRITICAL_SECTION 结构
44 CRITICAL_SECTION g_cs; 45 
46 //定义线程函数1
47 DWORD WINAPI ThreadFunOne(PVOID pvParam) ; 48 
49 //定义线程函数2
50 DWORD WINAPI ThreadFunTwo(PVOID pvParam); 51 
52 int main() 53 { 54 
55     //(2)初始化关键段 CRITICAL_SECTION
56     InitializeCriticalSection(&g_cs); 57 
58     //创建线程1
59     HANDLE hThreadOne = CreateThread(NULL,0,ThreadFunOne,0,0,NULL); 60  CloseHandle(hThreadOne); 61 
62     //创建线程2
63     HANDLE hThreadTwo = CreateThread(NULL,0,ThreadFunTwo,0,0,NULL); 64  CloseHandle(hThreadTwo); 65 
66     //让主线程先挂起,确保其它线程执行完成
67     Sleep(1000); 68     cout<<g_x<<endl; 69 
70     //(4)清理CRITICAL_SECTION结构,必须确保已经没有资源使用此关键段,否则会出现不可预料的结果
71     DeleteCriticalSection(&g_cs); 72     return 0 ; 73 } 74 
75 DWORD WINAPI ThreadFunOne(PVOID pvParam) 76 { 77     EnterCriticalSection(&g_cs) ; 78 
79     //共享的资源应该放在EnterCriticalSection和EnterCriticalSection函数之间
80     g_x++; 81 
82     EnterCriticalSection(&g_cs); 83     return 0; 84 } 85 
86 DWORD WINAPI ThreadFunTwo(PVOID pvParam) 87 { 88     EnterCriticalSection(&g_cs) ; 89 
90     //共享的资源应该放在EnterCriticalSection和EnterCriticalSection函数之间
91     g_x++; 92 
93     LeaveCriticalSection(&g_cs); 94     return 0; 95 } 96  

 

你可能感兴趣的:(线程同步)