操作系统 实验三:线程的互斥
实验三:线程的互斥
2.3.1实验⽬的
(1)熟练掌握Windows系统环境下线程的创建与撤销。
(2)熟悉Windows系统提供的线程互斥API。
(3)使⽤Windows系统提供的线程互斥API解决实际问题。
2.3.2 实验准备知识:相关API函数介绍
2.3.2.1临界区对象
临界区对象(CriticalSection)包括初始化临界区(InitializeCriticalSection())、进⼊临界区
( EnterCriticalSection ())、退出临界区( LeaveCriticalSection ())及删除临界区
(DeleteCriticalSection())等API函数。
初始化临界区
InitializeCriticalSection()⽤于初始化临界区对象。
原型:
VOID InitializeCriticalSection(
LPCRITICAL_SECTION lpCriticalSection
);
参数说明:
lpCriticalSection:指出临界区对象的地址。
返回值:
该函数没有返回值。
⽤法举例:
LPCRITCAL_SECTION hCriticalSection;
CRITICAL_SECTION Critical;
hCriticalSection=&Critical;
InitializeCriticalSection(hCriticalSection);
进⼊临界区
EnterCriticalSection()等待进⼊临界区的权限,当获得该权限后进⼊临界区。
原型:
VOID EnterCriticalSection(
LPCRITICAL_SECTION lpCriticalSection
);
参数说明:
lpCriticalSection:指出临界区对象的地址。
返回值:
该函数没有返回值。
⽤法举例:
LPCRITICAL_SECTION hCriticalSection;
CRITICAL_SECTION Critical;
hCriticalSection=&Critical;
EnterCriticalSection(hCriticalSection);
退出临界区
LeaveCriticalSection()释放临界区的使⽤权限。
原型:
VOID LeaveCriticalSection(
LPCRITICAL_SECTION lpCriticalSection );
参数说明:
lpCriticalSection:指出临界区对象的地址。
返回值:
该函数没有返回值
⽤法举例:
LPCRITICAL_SECTION hCriticalSection;
CRITICAL_SECTION Critical;
hCriticalSection=&Critical;
LeaveCriticalSection(hCriticalSection);
删除临界区
DeleteCriticalSection()删除与临界区有关的所有系统资源。
原型:
VOID DeleteCriticalSection(
LPCRITICAL_SECTION lpCriticalSection
);
参数说明:
lpCriticalSection:指出临界区对象的地址。
返回值:
该函数没有返回值。
⽤法举例:
LPCRITICAL_SECTION hCriticalSection;
CRITICAL_SECTION Critical;
hCriticalSection=&Critical;
DeleteCriticalSection(hCriticalSection);
2.3.2.2互斥对象
互斥对象(Mutex)包括创建互斥对象(CreateMutex())、打开互斥对象(OpenMutex())及释
放互斥对象(ReleaseMutex())API函数。
创建互斥对象
CreateMutex(0⽤于创建⼀个互斥对象。
原型:
HANDLE CreateMutex(
LPSECURITY_ATTRIBUTES lpMutexASributes,
BOOL bInitialOwner,
LPCTSTR lpName
);
参数说明:
lpMutexASributes:指定安全属性,为NULL时,信号量得到⼀个,默认的安全描述符。
bInitialOwner:指定初始的互斥对象。如果该值为TRUE并且互斥对象已经纯在,则调⽤线程获得互斥
对象的所有权,否则调⽤线程不能获得互斥对象的所有权。想要知道互斥对象是否已经存在,参⻅返回
值说明。
lpName:给出互斥对象的名字。
返回值:
互斥对象创建成功,将返回该互斥对象的句柄。如果给出的互斥对象是系统已经存在的互斥对象,将返回这个已存在互斥对象的句柄。如果失败,系统返回NULL,可以调⽤函数GetLastError()查询失败的
原因。
⽤法举例:
static HANDLE hHandle1=NULL;
//常⻅⼀个名为"MutexName1"的互斥对象
hHandle1=CreateMutex(NULL,FALSE, “MutexName1”);
打开互斥对象
OpenMutex()⽤于打开⼀个互斥对象。
原型:
HANDLE OpenMutex(
DWORD dwDesiredAccess,
BOOL bInheritHandle,
LPCTSTR lpName
);
参数说明:
指明系统安全属性⽀持的对互斥对象所有可能的访问。如果系统安全属性不⽀持,则不能获得对互
斥对象访问权。
(1)dwDesireAccess:指出发开后要对互斥对象进⾏何种访问,具体描述如表2-4所示。
表 2-4 对互斥对象的访问种类
访问 描述
MUTEX_ALL_ACCESS 可以进⾏对任何互斥对象的访问
SYNCHRONIZE 使⽤等待函数 wait functions 等待互斥对象成为可⽤状态或使⽤
ReleaseMutex()释放使⽤权,从⽽获得互斥对象的使⽤权
(2) bInheritHandle: 指出返回信号量的句柄是否可以继承。
(3) IpName : 给出信号量的名字。
返回值
互斥对象打开成功,将返回该互斥对象的句柄;如果失败,系统返回NULL,可以调⽤函数
GetLastError()查询失败的原因。
⽤法举例:
static HANDLE hHandle1 = NULL;
//打开⼀个名为"MutexName1"的互斥对象
hHandle=OpenMutex(SYNCHRONIZE,NULL,“MutexName1”);
- 释放互斥对象
ReleaseMutex() ⽤于释放互斥对象。
原型:
BOOL ReleaseMutex(
HANDLE hMUTEX;
);
参数说明:
hMutex:Mutex对象的句柄。CreateMutex()和OpenMutex()函数返回该句柄。
返回值:如果成功,将返回⼀个⾮0值;如果失败系统将返回0,可以调⽤函数 GetLastError()查询失败的原因。
⽤法举例:
sta2c HANDLE hHandle1=NULL;
BOOL rc;
rc= ReleaseMutex(hHandle1)
2.3.3 实验内容
完成两个⼦线程之间的互斥。在主线程中使⽤系统调⽤ CreateThread()创建两个⼦线程,并使两个⼦
线程互斥的使⽤全局变量 count。
2.3.4 实验要求
能正确的使⽤临界区对象,包括初始化临界区 Ini2alizeCri2calSec2on()、进⼊临界区
EnterCri2calSec2on()、退出临界区 LeaveCri2cal()及删除临界区 DeleteCri2calSec2on() 进⼀步理解线程
的互斥。
2.3.5 实验指导
具体操作过程同实验⼀,在 Microsoa Visual C++ 6.0 环境下建⽴⼀个MFC⽀持的控制台⼯程⽂件,编
写C程序,在主线程中使⽤Ini2alizeCri2calSec2on()初始化临界区,然后建⽴两个⼦线程,在两个⼦线程
中使⽤全局变量 count 的前、后分别使⽤EnterCri2calSea2on()进⼊临界区LeaveCri2calSec2on()退出临
界区,等两个⼦线程运⾏完毕,主线程使⽤DeleteCri2calSec2on()删除临界区并撤销线程。
2.3.6 实验总结
该试验完成了两个⼦线程之间的互斥。若去掉互斥对象,观察全局变量count的变化,了解互斥对象
的作⽤,进⼀步理解线程的互斥。本试验也可以使⽤互斥对象(Mutex)来完成两个线程的互斥,互斥对
象(Mutex)的使⽤⽅法与信号量对象相似,这⾥不再说明,请同学⾃⼰完成。线程互斥访问全局变量
count
如图 2-5所示。
2.3.7 源程序
#include "stdafx.h"
#include <Windows.h>#ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[ ]=__FILE__; #endif ////The one and only applica2on object CWinApp theApp; using namespace std; static int count =5; static HANDLE h1; static HANDLE h2; LPCRITICAL_SECTION hCriticalSection; //定义指向临界区对象的地址指针CRITICAL_SECTION Critical; //定义临界区void func1(); void func2(); int _tmain(int argc,TCHAR*argv[],TCHAR*envp[]) {int nRetCode=0; DWORD dwThreadID1, dwThreadID2; hCriticalSection=&Critical; //将指向临界区对象的指针指向临界区InitializeCriticalSection(hCriticalSection); //初始化临界区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(hCriticalSection); //删除临界区ExitThread(0); return nRetCode; } void func2() { int r2; EnterCriticalSection (hCriticalSection); //进?临界区r2=count; _sleep(100); r2=r2+1; count=r2; printf("count in func2=%d\n",count); LeaveCriticalSection (hCriticalSection); //退出临界区} void func1() { int r1; EnterCriticalSection (hCriticalSection); //进?临界区r1=count; _sleep(500); r1=r1+1; count=r1; printf("count in func1=%d\n",count); LeaveCriticalSection (hCriticalSection); //退出临界区
}
2.3.8 实验展望
上⾯的实验是使⽤临界区对象(Cri2calSec2on)实现的,同学们可以使⽤互斥对象(Mutex)来完
成。
在完成以上三个实验后,同学们对Windows系统提供的线程创建与撤销、线程的同步与互斥、API有
了⼀定的了解,在此基础上设计并完成⼀个综合性的实验解决实际同步与互斥问题,如⽣产者与消费者问题、读者与写者问题等。饰演的题⽬可以⾃⾏设计,但要求必须涉及线程的创建与撤销、等待对象函
数(waitFunc2ons)、信号量对象(Semaphore)临界区对象(Cri2calSec2on)或互斥对象(Mutex)的使
⽤。
操作系统 实验三:线程的互斥相关推荐
- linux中关于ssh实验,操作系统实验三linux的telnetftpssh的相关配置及验证
操作系统实验三linux的telnetftpssh的相关配置及验证 -1-昆明理工大学信息工程与自动化学院学生实验报告( 2010 -2011 学年第 二 学期 )课程名称:操作系统 开课实验室:信自 ...
- 操作系统实验三、进程通信
文章目录 操作系统实验三.进程通信 一.实验目的 二.实验内容 三.设计原理(或方案)及相关算法 四.结果分析 五.源代码 操作系统实验三.进程通信 一.实验目的 1.了解和熟悉Linux支持的消 ...
- 操作系统实验三进程间通信
文末也可直接获取实验文档 实验三 进程间通信 目录 1实验目的 2 实验内容 3实验详细操作步骤及程序清单: 4相关问题及思考 5总结 6背景知识 1实验目的 1.了解linux系统中进程通信的基本原 ...
- linux系统进程调度算法实验,操作系统实验三、进程调度算法实验
实验三.进程调度算法实验 3.1 实验目的 加深对进程调度概念的理解,体验进程调度机制的功能,了解Linux 系统中进程 调度策略的使用方法.练习进程调度算法的编程和调试技术. 3.2 实验说明 在 ...
- 超详细!操作系统实验三 系统调用(哈工大李治军)
实验3 系统调用 提醒 这次实验涉及的宏过于复杂,加上本人能力有限,我也没有花大量时间去研究每一段代码,只是理解到每一段代码做了什么这一程度. 实验目的 此次实验的基本内容是:在 Linux 0.11 ...
- 操作系统实验三:进程管理
实验三 进程管理 一.实验要求 (1)掌握操作系统中进程的基本概念: (2)掌握 Linux操作系统进程管理基本方法: (3)了解进程并发运行的过程. 二.实验内容 (1)验证实验: ① 启动vi编辑 ...
- 操作系统 实验三 进程调度模拟程序
实验三 进程调度模拟程序 ...
- 操作系统实验三:主存空间的分配与回收
实验三:主存空间的分配与回收 一.实验目的 通过本次实验,帮助学生理解在可变式分区管理方式下,如何实现主存空间的分配与回收. 二.实验内容 主存是中央处理机能直接存取指令和数据的存储器.能否合理而有效 ...
- 【操作系统】实验楼操作系统实验三——系统调用
操作系统实验3--系统调用 环境配置 首先同样是配置环境 cd /home/shiyanlou/oslab tar -zxvf hit-oslab-linux-20110823.tar.gz -C ...
最新文章
- 如何在ubuntu下使用samba创建共享
- 使用CmakeLists应该知道的一些知识
- Sklearn参数详解—聚类算法
- jop怎么读音英语怎么说_“春晚”英语怎么说?
- python接口编程的好处_python接口自动化测试
- 微信小程序全面开放近一年,姗姗来迟的阿里还有胜局吗?| 畅言
- Atitit.分布式远程调用 rpc rmi CORBA的关系
- linux打包除了某个文件夹,tar打包且排除某个文件
- android脚本模拟器,android运行模拟器脚本(批处理)
- Android 查询局域网内所有ip和mac地址
- 51单片机 | 步进电机实验
- android(4) 使用ViewPaper 以及这几年来的一些感悟
- 算法题:最少出牌次数
- DxO PhotoLab 2.2.2完整精华汉化版|顶级RAW数码后期软件
- 局域网arp攻击_本地复现 ARP欺骗攻击
- 关于jquery的click()和trigger(‘click‘)方法的一点问题
- Kubernetes(四) - Pod和Deployment
- C300 简单配置
- python大规模获取豆瓣影评_Python 获取豆瓣用户电影收藏数据
- 隆重推荐:隐身专家V2.91下载!