首页 > 代码库 > 线程同步——用户模式下线程同步——关键段实现线程同步
线程同步——用户模式下线程同步——关键段实现线程同步
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 //定义线程函数147 DWORD WINAPI ThreadFunOne(PVOID pvParam) ;48 49 //定义线程函数250 DWORD WINAPI ThreadFunTwo(PVOID pvParam);51 52 int main()53 {54 55 //(2)初始化关键段 CRITICAL_SECTION56 InitializeCriticalSection(&g_cs);57 58 //创建线程159 HANDLE hThreadOne = CreateThread(NULL,0,ThreadFunOne,0,0,NULL);60 CloseHandle(hThreadOne);61 62 //创建线程263 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
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。