012244信安1401杨紫淇 计算机操作系统22.docx
- 文档编号:5363107
- 上传时间:2022-12-15
- 格式:DOCX
- 页数:16
- 大小:172.89KB
012244信安1401杨紫淇 计算机操作系统22.docx
《012244信安1401杨紫淇 计算机操作系统22.docx》由会员分享,可在线阅读,更多相关《012244信安1401杨紫淇 计算机操作系统22.docx(16页珍藏版)》请在冰豆网上搜索。
012244信安1401杨紫淇计算机操作系统22
实验报告
课程名称《计算机操作系统》_
实验项目__________
实验仪器PC机一台
系别______信息管理学院__
专业__信息安全
班级/学号信安14012014012244__________________
学生姓名__杨紫淇______________
实验日期_____2016.4.7___
成绩___________________
指导教师_______刘亚辉_____
北京信息科技大学
信息管理学院
(课程上机)实验报告
实验课程名称:
计算机操作系统专业:
信息安全
班级:
信安1401学号:
2014012244姓名:
杨紫淇成绩:
实验名称
线程的同步
实验地点
实验时间
2016.4.7
1.实验目的:
进一步掌握windows系统环境下线程的创建和撤销
熟悉windows系统提供的线程同步API
使用windows系统提供的线程同步API解决实际问题
2.实验内容:
完成主子两个线程之间的同步,要求子线程先执行。
在主线程中使用系统调用
CreateThread()创建一个子线程。
主线程创建一个子线程后进入阻塞状态,直到子线程运
行完毕后唤醒主线程。
3.实验要求:
能正确使用等待对象、WaitForSingleObject()或WaitForMultipleObject(0及信号量对
象CreateSemaphore()、OpenSemaphore()、ReleaseSemaphore()等系统调用,进一步
理解线程的同步。
4.实验准备:
相关API函数介绍
5.试验指导:
具体操作过程同本章实验一,在MicrosoftvisualC++6.0环境下建立一个MFC支持的控
制台文件,编写C程序,在程序中使用CreateSemaphore(NULL,0,1,”SemaphoreName1”)
创建一个名为“SemaphoreName1”的信号量,信号量的初始值为0,之后使用OpenSemaphore
(SYNCHRONIZE|SEMAPHORE_MODIFY_STARTE,NULL,”SemaphoreName1)打开该信号量,这
里访问标志使用“SYNCHRONIZE|SEMAPHORE_MODIFY_STARTE”,以便之后可以使用
WaitForSingleObject()等待该信号量及使用ReleaseSemaphore()释放该信号量,然后创
建一个子线程,主线程创建子线程后调用WaitForSingleObject(hHandle1,INFINITE),这里
等待时间设置为INFINITE表示一直等待下去,直到该信号量被唤醒为止。
子线程结束,调用
ReleaseSemaphore(hHandle1,1,NULL)释放信号量,使信号量的值加1。
6.实验过程:
7.实验总结:
实验完成了主、子线程的同步,主线程创建子线程后,主线程塞,让子线程先执行,等
子线程执行完后,由子线程唤醒子线程。
主子线程运行情况如图:
主、子线程的运行情况
说明:
1.实验名称、实验目的、实验内容、实验要求由教师确定,实验前由教师事先填好,然后作为实验报告模版供学生使用;
2.实验准备由学生在实验或上机之前填写,教师应该在实验前检查;
3.实验过程由学生记录实验的过程,包括操作过程、遇到哪些问题以及如何解决等;
4.实验总结由学生在实验后填写,总结本次实验的收获、未解决的问题以及体会和建议等;
5.源程序、代码、具体语句等,若表格空间不足时可作为附录另外附页。
源程序:
//Thread.cpp:
Definestheentrypointfortheconsoleapplication.
#include"stdafx.h"
#include"Thread.h"
#ifdef_DEBUG
#definenewDEBUG_NEW
#undefTHIS_FILE
staticcharTHIS_FILE[]=__FILE__;
#endif
//Theoneandonlyapplicationobject
CWinApptheApp;
usingnamespacestd;
voidThreadName()
{
printf("ThreadisRunning!
\n");
}
staticHANDLEhHandle1=NULL;
DWORDThreadID1;
int_tmain(intargc,TCHAR*argv[],TCHAR*envp[])
{
intnRetCode=0;
hHandle1=CreateThread((LPSECURITY_ATTRIBUTES)NULL,
0,
(LPTHREAD_START_ROUTINE)ThreadName,
(LPVOID)NULL,
0,
&ThreadID1);
Sleep(5000);
CloseHandle(hHandle1);
ExitThread(0);
returnnRetCode;
//initializeMFCandprintanderroronfailure
if(!
AfxWinInit(:
:
GetModuleHandle(NULL),NULL,:
:
GetCommandLine(),0))
{
//TODO:
changeerrorcodetosuityourneeds
cerr<<_T("FatalError:
MFCinitializationfailed")< nRetCode=1; } else { //TODO: codeyourapplication'sbehaviorhere. CStringstrHello; strHello.LoadString(IDS_HELLO); cout<<(LPCTSTR)strHello< } returnnRetCode; } voidThreaName1() {printf("ThreadisRunning! ! \n"); } 【注意】: 文件的路径一定是能够匹配的。 【基础知识】: (1)lpThreadAttributes: 为线程指定安全属性.为NULL时,线程得到一个默认的安全描述符. (2)dwStackSize: 线程堆栈的大小.其值为0时,其大小与调用该线程的线程堆栈大小相同. (3)lpStartAddress: 指定线程要执行的函数. (4)lpparameter: 函数中要传递的参数. (5)dwCreationFlags: 指定线程创建后所处的状态.若为CRRATE_SUSPENDED,表示创建后出 于挂起状态,用ResumeThread()激活线程才可以执行.若该值为0,表示线程创建后立即执行. (6)lpThreadId: 用一个32位的变量接受系统返回的线程标识符.若该值设为NULL,系统不 返回线程标识符. 2.2线程的同步 //Semaphore.cpp: Definestheentrypointfortheconsoleapplication. #include"stdafx.h" #include"Semaphore.h" #ifdef_DEBUG #definenewDEBUG_NEW #undefTHIS_FILE staticcharTHIS_FILE[]=__FILE__; #endif //Theoneandonlyapplicationobject CWinApptheApp; usingnamespacestd; staticHANDLEh1;//线程句柄 staticHANDLEhHandle1=NULL;//信号量句柄 voidfunc(); int_tmain(intargc,TCHAR*argv[],TCHAR*envp[]) { intnRetCode=0; DWORDdwThreadID1; DWORDdRes,err; hHandle1=CreateSemaphore(NULL,0,1,"SemaphoreName1");//创建一个信号量 if(hHandle1==NULL)printf("SemaphoreCreate! \n"); elseprintf("SemaphoreCreateSuccess! \n"); hHandle1=OpenSemaphore(SYNCHRONIZE|SEMAPHORE_MODIFY_STATE, NULL, "SemaphoreName1");//打开信号量 if(hHandle1==NULL)printf("SemaphoreOpenFail! \n"); elseprintf("SemaphoreOpenSuccess! \n"); h1=CreateThread((LPSECURITY_ATTRIBUTES)NULL, 0, (LPTHREAD_START_ROUTINE)func, (LPVOID)NULL, 0,&dwThreadID1);//创建子进程 if(h1==NULL)printf("Thread1createFail! \n"); elseprintf("Thread1createSuccess! \n"); dRes=WaitForSingleObject(hHandle1,INFINITE);//主线程等待子线程结束 err=GetLastError(); printf("WaitForSingleObjecterr=%d\n",err); if(dRes==WAIT_TIMEOUT)printf("TIMEOUT! dRes=%d\n",dRes); elseif(dRes==WAIT_OBJECT_0)printf("WAIT_OBJECT! dRes=%d\n",dRes); elseif(dRes==WAIT_ABANDONED) printf("WAIT_ABANDONED! Dres=%d\n",dRes); elseprintf("dRes=%d\n",dRes); CloseHandle(h1); CloseHandle(hHandle1); ExitThread(0); returnnRetCode; } voidfunc() { BOOLrc; DWORDerr; printf("NowInThread! \n"); rc=ReleaseSemaphore(hHandle1,1,NULL); err=GetLastError(); printf("ReleaseSemaphoreerr=%d\n",err); if(rc==0)printf("SemaphoreReleaseFail! \n"); elseprintf("SemaphoreReleaseSuccess! rc=%d\n",rc); } 运行情况: 【基础知识】: 等待对象(waitfuctions)函数包括等待一个对象(WaitForSingleObject())和等待多对 象(WaitForMultipleObject())两个API函数。 等待一个对象 WaitForMultipleObject()用于等待一个对象。 他等待的对象可以为以下对象之一。 Changenotification: 变化通知。 Consoleinput: 控制台输入。 Events: 事件。 Job: 作业。 Mutex: 互斥信号量。 Process: 进程。 Semaphore: 计数信号量。 Thread: 线程。 Waitabletimer: 定时器。 原型: DWORDWaitForSingleObject( HANDLEhHandle,//对象句柄 DWORDdwMilliseconds//等待时间 ); 参数说明: hHandle: 等待对象的对象句柄。 该对象句柄必须为SYNCHRONIZE访问。 dwMilliseconds: 等待时间,单位为ms。 若改值为0,函数在测试对象的状态后立即返 回,若为INFINITE,函数一直等待下去,直到收到一个信号将其唤醒,如表2‐1所示。 返回值: 如果返回成功,其返回值说明是何种事件导致函数返回。 表2‐1函数描述 访问描述 WAIT_ABANDONED等待对象的是一个互斥(mutex)对象,该互斥对象没有被拥 有它的线程释放,他被设置为不能被唤醒 WAIT_OBJECT_0指定对象被唤醒 WAIT_TIMEOUT超时 用法举例: StaiticHANDLEhHandle1=NULL; DWORDdRes; dRes=WaitForSingleObject(hHandle1,10);//等待对象的句柄为hHandle,等待时间为 1000ms 等待多个对象 WaitForMultipleObject()在指定时间内等待多个对象,他等待的对象与 WaitForSingleObject()相同。 原型: DWORDWaitForMultipleObject( DWORDnCount,//句柄数组中的句柄数 XONSTHANDLE*lpHandles,//指向对象句柄数组的指针 BOOLfWaitAll,//等待类型 DWORDdwMilliseconds//等待时间 ); 参数说明: nCount: 由指针*lpHandles指定的句柄数组中的句柄数,最大数是 MAXIMUM_WAIT_OBJECTS。 *lpHandles: 指向对象句柄数组的指针。 fWAitAll: 等待类型。 若存为true,当由lpHandles数组指定的所有对象被唤醒时函数返 回;若为FALSE,当由lpHandles数组制定的某一个对象被唤醒时函数返回,且有返回值说 明事由哪个对象引起的函数返回。 dwMilliseconds: 等待时间。 单位为ms。 若该值为0,函数测试对象的状态后立即返回; 若为INFINITE,函数一直等待下去,直到收到一个信号将其唤醒。 返回值: 如果成功返回,其返回值说明是何种事件导致函数返回。 各参数的描述如表2‐2所示。 表2‐2各参数描述 访问描述 WAIT_OBJECT_0to(WAIT_OBJECT若bWaitAll为TRUE,返回值说明所有被等待的对象均 被唤醒;若 _0+nCount‐1)bWaitAll为FALSE。 返回值减去WAIT_OBJECT_0说明 lpHandles数组下标指定的对象满足等待条件。 如果调用时多个对象同时被唤醒,则取多个 对象中最小的那个数组下标 WAIT_ABANDONED_0to若bWaitAll为TRUE,返回值说明所有被等带的对象 均被唤醒,并且(WIAT_ABANDONED‐0+NcOUNT‐1)至少有一个对象是没有约束的互斥 对象;若bWaitAll 为FALSE,返回值减去WAIT_ABANDONED_0说明lpHandles数组下标指定的没有约束的互斥 对象满足等待条件 WAIT_TIMNEOUT超时且参数bWaitAll指定的条件不能满足 信号量对象(semaphore) 信号量对象(semaphore)包括创建信号量(CreateSemaphore())打开信号量 OpenSemaphore()及增加信号量的值(ReleaseSemaphore())API函数。 创建信号量 CreateSemaphore()用于创建一个信号量。 原型: HANDLECreateSemaphore( LPSECURITY_ATTRIBUTESlpSemaphoreAttributes,//安全属性 LONGlInitialCount,//信号量对象初始值 LONGliMaximumCount,//信号量最大值 LPCTSTRlpName//信号量名 ); 参数说明: lpSemaphoreAttributes: 指定安全属性,为null是,信号量得到一个默认的安全描述符。 lInitialCount: 指定信号量对象的初始值。 该值必须大于等于0,小于等于 lMaximumCount。 当其值大于0是,信号量被唤醒。 当该函数释放了一个等待该信号量的 线程时,lInitialCount值减1,当调用函数ReleaseSemaphore()时,按其指定的数量加一个值。 lMaximumCount: 指出该信号量的最大值,该值必须大于0. lpName: 给出该信号量的名字。 返回值: 信号量创建成功,将返回该型号量的句柄。 如果给出的信号量名是系统已经存在的信号 量,将返回这个已经存在的信号量的句柄。 如果失败,系统返回null,还可以调用函数 GEtLastError()查询失败的原因。 用法举例: StaticHANDLEhHandle1=null; //创建一个信号量,其初值为0,最大值为5,信号量的名字为“SemphoreName1” hHnadle1=CreateSemaphore(NULL,0,5,"SemphoreName1"); 打开信号量 OpenSemaphore()用于打开一个信号量。 原型: HANDLEOpenSemaphore( DWORDdwDesidedAccess,//访问标志 BOOLbInheritHandle,//继承标志 LPCTSTRlpNme//信号量名 ); 参数说明: (1).dwDesiredAccess: 指出打开后要对信号量进行何种访问,如表2-3所示。 表2‐3访问状态 访问描述 SEMAPHORE_ALL_ACCESS可以进行任何对信号量的访问 SEMPHORE_MODFIY_STATE可以使用ReleaseSemaphore()修改信号量的值,使信号量 的值成为可用状态 SYNCHRONIZE使用等待函数(waitfunctions),等待信号量成为可用状态 (2).bInheritHandle: 指出返回的的信号量句柄是否可以继承。 (3).lpName: 给出信号量的名字 返回值: 信号量打开成功,将返回信号量的句柄;如果失败,系统返回null,可以调用函数 GetLastError()查询失败的原因。 ; 用法举例: StaticHANDLEhHandle1=null; //打开一个名为”SemphoreName1”的信号量,之后可使用ReleaseSemaphore()函 数增加信号量的值hHandle1=OpenSemaphore(SEMAPHORE_MOFDIFY_START,NULL,” SemphoreName1”); 3.增加信号量的值 ReleaseSemaphore()用于增加信号量的值。 原型: BOOLReleaseSemaphore( HANDLEhSemaphore,//信号量对象句柄 LONGlReleaseCount,//信号量要增加数值 LPLONGlpPreiousCount//信号量要增加数值地址 ); 参数说明: (1).hSemaphore: 创建或打开信号量时给出的信号量对象句柄。 WindowsNT中建议 使用SEMAPHORE_MODIFY_STARTE访问属性打开该信号量。 (2).lReleaseCount: 信号量要增加数值。 该值必须大于0。 如果增加该值后大于信号 创建时给出的lMaximumCount值,则增加操作失效,函数返回FALSE。 (3).lpPreiousCount: 接收信号量的一个32位的一个变量。 若不需要接受该值,可 以指定为null。 返回值: 如果成功,将返回一个非0值;如果失败,系统返回一个0,可以调用一个GetLastError ()查询失败的原因。 用法举例: StaticHANDLEhHandle1=NULL; BOOLrc; rc=ReleaseSemaphore(hHandle1,1,NULL);//给信号量的值加1;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 012244信安1401杨紫淇 计算机操作系统22 012244 1401 杨紫淇 计算机 操作系统 22