操作系统实验线程的同步.docx
- 文档编号:27307848
- 上传时间:2023-06-29
- 格式:DOCX
- 页数:8
- 大小:17.63KB
操作系统实验线程的同步.docx
《操作系统实验线程的同步.docx》由会员分享,可在线阅读,更多相关《操作系统实验线程的同步.docx(8页珍藏版)》请在冰豆网上搜索。
操作系统实验线程的同步
实验六 线程的同步
1、实验目的
(1)进一步掌握Windows系统环境下线程的创建与撤销。
(2)熟悉Windows系统提供的线程同步API。
(3)使用Windows系统提供的线程同步API解决实际问题。
2、实验准备知识:
相关API函数介绍
1等待对象
等待对象(waitfunctions)函数包括等待一个对象(WaitForSingleObject())和等待多个对象(WaitForMultipleObject())两个API函数。
1)等待一个对象
WaitForSingleObject()用于等待一个对象。
它等待的对象可以为以下对象之一。
·Changeontification:
变化通知。
·Consoleinput:
控制台输入。
·Event:
事件。
·Job:
作业。
·Mutex:
互斥信号量。
·Process:
进程。
·Semaphore:
计数信号量。
·Thread:
线程。
·Waitabletimer:
定时器。
原型:
DWORDWaitForSingleObject(
HANDLE hHandle, //对象句柄
DWORDdwMilliseconds // 等待时间
);
参数说明:
(1)hHandle:
等待对象的对象句柄。
该对象句柄必须为SYNCHRONIZE访问。
(2)dwMilliseconds:
等待时间,单位为ms。
若该值为0,函数在测试对象的状态后立即返回,若为INFINITE,函数一直等待下去,直到接收到一个信号将其唤醒,如表2-1所示。
返回值:
如果成功返回,其返回值说明是何种事件导致函数返回。
表2-1 函数描述
访问
描述
WAITABANDONED
等待的对象是一个互斥(Mutex)对象,该互斥对象没有被拥有它的线程释放,它被设置为不能被唤醒
WAITOBJECT0
指定对象被唤醒
WAITTIMEOUT
超时
用法举例:
Static HANDLEhHandlel=NULL;
DWORD dRes;
dRes=WaitForSingleObject(hHandlel,10); //等待对象的句柄为hHandlel,等待时间为10ms
2)等待对个对象
WaitForMultiple()bject()在指定时间内等待多个对象,它等待的对象与WaitForSingleObject()相同。
原型:
DWORDWaitForMultipleObjects(
DWORDnCount, //句柄数组中的句柄数
CONSTHANDLE*lpHandles, //指向对象句柄数组的指针
BOOLfWaitAll, //等待类型
DWORDdwMilliseconds //等待时间
);
参数说明:
(1)nCount:
由指针*lpHandles指定的句柄数组中的句柄数,最大数是MAXIMUMWAITOBJECTS。
(2)*lpHandles:
指向对象句柄数组的指针。
(3)fWaitAll:
等待类型。
若为TRUE,当由lpHandles数组指定的所有对象被唤醒时函数返回;若为FALSE,当由lpHandles数组指定的某一个对象被唤醒时函数返回,且由返回值说明是由于哪个对象引起的函数返回。
(4)dwMilliseconds:
等待时间,单位为ms。
若该值为0,函数测试对象的状态后立即返回;若为INFINITE,函数一直等待下去,直到接收到一个信号将其唤醒。
返回值:
、
如果成功返回,其返回值说明是何种事件导致函数返回。
各参数的描述如表2-2所示。
表2-2 各参数描述
访问
描述
WAITOBJECT0to(WAIT
OBJECT0+nCount-1)
若bWaitAll为TRUE,返回值说明所有被等待的对象均被唤醒;若bWaitAll为FALSE,返回值减去WAITOBJECT0说明lpHandles数组下标指定的对象满足等待条件。
如果调用时多个对象同时被唤醒,则取多个对象中最小的那个数组下标
WAITABANDONED0to(WAIT
ABANDONED0+nCount-1)
若bWaitAll为TRUE,返回值说明所有被等待的对象均被唤醒,并且至少有一个对象是没有约束的互斥对象;若bWaitAll为FALSE,返回值减去WAITABANDONED0说明lpHandles数组下标指定的没有约束的互斥对象满足等待条件
WAITTIMEOUT
超时且参数bWaitAll指定的条件不能满足
2信号量对象(Semaphore)
信号量对象(Semaphore)包括创建信号量(CreateSemaphore())、打开信号量(OpenSemaphore())及增加信号量的值(ReleaseSemaphore())API函数。
1)创建信号量
CreateSemaphore())用于创建一个信号量。
原型:
HANDLECreateSemaphore(
LPSECURITYATTRIBUTESlpSemaphoreAttributes, //安全属性
LONGlInitialCount, //信号量对象的初始值
LONGlMaximumCount, //信号量的最大值
LPCTSTR lpName //信号量名
);
参数说明:
(1)lpSemaphoreAttributes:
指定安全属性,为NULL时,信号量得到一个
默认的安全描述符。
(2)lInitialCount:
指定信号量对象的初始值。
该值必须大于等于0,小于等于lMaximumCount。
当其值大于0时,信号量被唤醒。
当该函数释放了一个等待该信号量的线程时,lInitialCount值减1,当调用函数ReleaseSemaphore()时,按其指定的数量加一个值。
(3)lMaximumCount:
指出该信号量的最大值,该值必须大于0。
(4)lpName:
给出信号量的名字。
返回值:
信号量创建成功,将返回该信号量的句柄。
如果给出的信号量名是系统已经存在的信号量,将返回这个已存在信号量的句柄。
如果失败,系统返回NULL,可以调用函数GetLastError()查询失败的原因。
用法举例:
StaticHANDLEhHandlel=NULL; //定义一个句柄
//创建一个信号量,其初始值为0,最大值为5,信号量的名字为“SemphoreNamel”
HHandle=CreateSemaphore(NULL,0,5,“SemphoreNamel”);
2)打开信号量
OpenSemaphore()用于打开一个信号量。
原型:
HANDLEOpenSemaphore(
DWORDdWDesiredAccess, //访问标志
BOOLbInheritHandle, //继承标志
LPCTSTRlpName //信号量名
);
参数说明:
(1)dwDesiredAccess:
指出打开后要对信号量进行何种访问,如表2-3所示。
表2-3 访问状态
访问
描述
SEMAPHOREALLACCESS
可以进行任何对信号量的访问
SEMAPHOREMODIFYSTATE
可使用ReleaseSemaphore()修改信号量的值,使信号量成为可用状态
SYNCHRONIZE
使用等待函数(waitfunctions),等待信号量成为可用状态
(2)bInheritHandle:
指出返回的信号量句柄是否可以继承。
(3)lpName:
给出信号量的名字。
返回值:
信号量打开成功,将返回该号量的句柄;如果失败,系统返回NULL,可以调用函数GetLastError()查询失败的原因。
用法举例:
static HANDLEhHandlel=NULL;
//打开一个名为“SemphoreNamel”的信号量,之后可使用ReleaseSemaphore()函数增加信号量的值hHandlel=OpenSemaphore(SEMAPHOREMODIFYSTATE,NULL,“SemphoreNamel”);
3)增加信号量的值
ReleaseSemaphore()用于增加信号量的值。
原型:
BOOLReleaseSemaphore(
HANDLEhSemaphore, //信号量对象句柄
LONGlReleaseCount, //信号量要增加数值
LPLONGlpPreviousCount //信号量要增加数值的地址
);
参数说明:
(1)hSemaphore:
创建或打开信号量时给出的信号量对象句柄。
WindowsNT中建议要使用SEMAPHOREMODIFYSTATE访问属性打开该信号量。
(2)IReleaseCount:
信号量要增加的数值。
该值必须大于0。
如果增加该值后,大于信号量创建时给出的lMaximumCount值,则增加操作失效,函数返回FALSE。
(3)LpPreviousCounte:
接收信号量值的一个32位的变量。
若不需要接收该值,可以指定为NULL。
返回值:
如果成功,将返回一个非0值;如果失败,系统返回0,可以调用函数GetLastError()查询失败的原因。
用法举例:
static HANDLEhHandlel=NULL;
BOOLrc;
Rc=ReleaseSemaphore(hHandlel,l,NULL); //给信号量的值加1
3、实验内容
完成主、子两个线程之间的同步,要求子线程先执行。
在主线程中使用系统调用GreateThread()创建一个子线程。
主线程创建子线程后进入阻塞状态,直到子线程运行完毕后唤醒主线程。
4、实验要求
能正确使用等待对象WaitForSingleObject()或WaitForMultipleObject()及信号量对象CreateSemaphore()、OpenSemaphore()、ReleaseSemaphore()等系统调用,进一步理解线程的同步。
5、实验指导
具体操作过程:
在Microsoft VisualC++6.0环境下建立一个MFC支持的控制台工程文件,编写C程序,在程序中使用CreateSemaphore(NULL,0,1,“SemaphoreNamel”)创建一个名为“SemaphoreNamel”的信号量,信号量的初始值为0,之后使用0penSemaphore(SYNCHRONIZE|SEMAPHOSEMODIFYSTATE,NULL,“SemaphoreNamel”)打开该信号量,这里访问标志用“SYNCHRONIZE|SEMAPHOREMODIFYSTATE”,以便之后可以使用WaitForSingleObject()等待该信号量及使用ReleaseSemaphore()释放该信号量,然后创建一个子线程,主线程创建子线程后调用WaitForSingleObject(hHandlel,INFINITE),这里等待时间设置为INFINITE表示要一直等待下去,直到该信号量被唤醒为止。
子线程结束,调用ReleaseSemaphore(hHandlel,1,NULL)释放信号量,使信号量的值加1。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 操作系统 实验 线程 同步