实验三:线程的互斥

一:实验目的

(1)掌握线程的创建与撤销。
(2)熟悉Windows系统提供的线程互斥API。

二:相关知识点

1.临界区对象(CriticalSection)
初始化临界(InitializeCriticalSection())
进⼊临界区(hEnterCriticalSection ())
退出临界区( LeaveCriticalSection ())
删除临界区 (DeleteCriticalSection())等API函数。

1.初始化临界区
InitializeCriticalSection()⽤于初始化临界区对象。 
原型: 
VOID InitializeCriticalSection( 
LPCRITICAL_SECTION lpCriticalSection 
);

2.进⼊临界区 
EnterCriticalSection()等待进⼊临界区的权限,当获得该权限后进⼊临界区。 
原型: 
VOID EnterCriticalSection( 
LPCRITICAL_SECTION lpCriticalSection 
);

3.退出临界区 
LeaveCriticalSection ()释放临界区的使⽤权限。 
原型: 
VOID LeaveCriticalSection ( 
LPCRITICAL_SECTION lpCriticalSection  ); 

4.删除临界区 
DeleteCri2calSec2on()删除与临界区有关的所有系统资源。 
原型: 
VOID DeleteCri2calSec2on( 
LPCRITICAL_SECTION lpCri2calSec2on 
); 

以上函数均没有返回值

2.互斥对象
互斥对象(Mutex)包括创建互斥对象(CreateMutex())、打开互斥对象(OpenMutex())及释 放互斥对象(ReleaseMutex())API函数。

1.创建互斥对象 
CreateMutex()⽤于创建⼀个互斥对象。 
原型: 
HANDLE CreateMutex( 
LPSECURITY_ATTRIBUTES lpMutexASributes, 
BOOL bInitialOwner, 
LPCTSTR lpName 
); 

2.打开互斥对象 
OpenMutex()⽤于打开⼀个互斥对象。 
原型: 
HANDLE OpenMutex( 
DWORD dwDesiredAccess, 
BOOL bInheritHandle, 
LPCTSTR lpName 
);

3. 释放互斥对象 
ReleaseMutex() ⽤于释放互斥对象。 
原型: 
BOOL ReleaseMutex( 
HANDLE hMutex; 
); 

三、实验内容

完成两个⼦线程之间的互斥。在主线程中使⽤系统调⽤ CreateThread()创建两个⼦线程,并使两个⼦ 线程互斥的使⽤全局变量 count。

四、实验要求

能正确的使⽤临界区对象,包括初始化临界区 InitializeCriticalSection()、进⼊临界区 EnterCriticalSection()、退出临界区 LeaveCritical()及删除临界区 DeleteCriticalSection() 进⼀步理解线程 的互斥。

五、部分代码及运行结果

LPCRITICAL_SECTION CriticalSection; //定义指向临界区对象的地址指针

CRITICAL_SECTION Critical; //定义临界区

      CriticalSection= &Critical; //将指向临界区对象的指针指向临界区
      InitializeCriticalSection(CriticalSection); //初始化临界区
      h1=CreateThread((LPSECURITY_ATTRIBUTES)NULL, 
      0, 
      (LPTHREAD_START_ROUTINE)func1, 
      (LPVOID)NULL, 
      0,&dwThreadID1); //创建线程 func1 
      if (h1==NULL) printf("Thread1 create FAIL!\n"); 
      else printf("Thread1 create Success!\n");
      h2=CreateThread((LPSECURITY_ATTRIBUTES)NULL, 
      0, 
      (LPTHREAD_START_ROUTINE)func2, 
      (LPVOID)NULL, 
      0,&dwThreadID2); //创建线程 func2 
      if (h2==NULL) printf ("Thread2 create FAIL!\n"); 
      else printf ("Thread2 create Success!\n");
      Sleep(1000); 
      CloseHandle(h1); 
      CloseHandle(h2); 
      DeleteCriticalSection(CriticalSection); //删除临界区
      ExitThread(0);
      return nRetCode; 
} 
     void func2() 
	 { int r2; 
       EnterCriticalSection (CriticalSection); //进入临界区
       r2=count; 
       _sleep(100); 
      r2=r2+1; 
      count=r2; 
      printf("count in func2=%d\n",count);
      LeaveCriticalSection (CriticalSection); //退出临界区
	 } 
void func1() 
{ 
	int r1; 
     EnterCriticalSection (CriticalSection); //进入临界区
     r1=count; 
     _sleep(500); 
    r1=r1+1; 
    count=r1; 
    printf("count in func1=%d\n",count); 
    LeaveCriticalSection (CriticalSection);

}

运行结果
在这里插入图片描述

六、实验总结

我认为此次实验最重要的是将各个函数的原型记住,能够认清并掌握运用各个函数所能实现的功能。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

就躺了吧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值