2025年操作系统实验报告攻略河北工业大学深度解析与实践心得_第1页
2025年操作系统实验报告攻略河北工业大学深度解析与实践心得_第2页
2025年操作系统实验报告攻略河北工业大学深度解析与实践心得_第3页
2025年操作系统实验报告攻略河北工业大学深度解析与实践心得_第4页
2025年操作系统实验报告攻略河北工业大学深度解析与实践心得_第5页
已阅读5页,还剩76页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

试验一进程控制与描述WindowsXP进程的"毕生"。二、试验环境三、试验内容和环节WindowsXP可以识别的程序包括控制台应用程序、GUI应用程序和服务应用程序。1、简朴的控制台应用程序[}2、GUI应用程序}也可以运用任何其他文本编辑器键入程序代码,假如这样,例如使用WORD来键入和编辑程序,则应当注意什么问题?在“命令提醒符”窗口运行CLEXE,产生1-2.EXE文献:在程序1-2的GUT应用程序中,首先需要Windows.h头文献,以便获得传送给WinMainO和MessageBox)API函数的数据类型定义。接着的pragma指令指示编译器连接器找到User32.LIB库文献并将其与产生的EXE文献连接起来。这样就可以运行简朴的命令行命令CLMsgBox.CPP来创立这一应用程序,假如没有pragma指令,则MessageBox)API函数就成为未定义的了。这一指令是VisualStudioC++编译器特有的。接下来是WinMainO措施。其中有四个由实际的低级入口点传递来的参数。hlnstance参数用来装入与代码相连的图标或位图一类的资源,无论何时,都可用GetModuleHandleOAPI函数将这些资源提取出来。系统运用实例句柄来指明代码和初始的数据装在内存的何处。句柄的数值实际上是EXE文献映像的基地址,一般为0x00400000。下一种参数hPrevInstance是为向后兼容而设的,目前系统将其设为NULL。应用程序的命令行(不包括程序的名称)是IpCmdLine参数。此外,系统运用nCmdShow参数告诉应用程序怎样显示它的主窗口(选项包括最小化、最大化和正常)。最终,程序调用MessageBox0)API函数并退出。假如在进入消息循环之前就结束运行的话,最终必须返回0。运行成果(试将其中的信息与程序1-1.EXE的运行成果进行比较):弹出一种消息框,标题为Greetings,内容为Hello,Windows,中间有一种确认按钮3、进程对象操作系统将目前运行的应用程序看作是进程对象。运用系统提供的惟一的称为句柄(HANDLE)的号码,就可与进程对象交互。这一号码只对目前进程有效。本试验表达了一种简朴的进程句柄的应用。在系统中运行的任何进程都可调用GetCurrentProcessOAPI函数,此函数可返回标识进程自身的句柄。然后就可在Windows需要该进程的有关状况时,运用这一句柄来提供。程序1-3:获得和使用进程的句柄(std:cout<<"Currentproces{程序1-3中列出的是一种获得进程句柄的措施。对于进程句柄可进行的惟一有用的操作是在API调用时,将其作为参数传送给系统,正如程序1-3中对GetPriorityClassOAPI函数的调用那样。在这种状况下,系统向进程对象内“窥视”,以决定其优先级,然后将此优先级返回给应用程序。OpenProcessO和CreateProcessOAPI函数也可以用于提取进程句柄。前者提取的是已经存在的进程的句柄,而后者创立一种新进程,并将其句柄提供出来。在“命令提醒符”窗口运行CLEXE,产生1-3.EXE文献:将程序1-4.cpp程序键入记事本中,并把代码保留为1-4.cpp。程序1-4显示怎样找出系统中正在运行的所有进程,怎样运用OpenProcessOAPI函数来获得每一种访问进程的深入信息。程序1-4运用句柄查出进程的详细信息//proclist项目DWORDGetKemelModePerc(/将构造转化为64位整数(((ULONGLONG)ftKerneldwHighDate(((ULONGLONG)ftUser.dwHighDateULONGLONGqwTotal=qwKernel+qwU(DWORD)((ULONGLONG)100*qwKernel(/对目前系统中运行的进程拍取“快照”HANDLEhSnapshot=::CreateToolhelp32SnTH32CS-SNAPPROCESS,//提取目前进程BOOLbMore=::Process32First(hSnapshoHANDLEhProcess=::OpenPrpe.th32ProcessID);//要打开的{ftCreation,ftExit,ftKemelMode,hProcess,/所感爱好的进程&ftCreation,//进&ftExit,/结束时间(假如有的话)&ftKernelMode,/在内核模DWORDdwPctKernel=::GetKernelModePerstd::cout<<"ProcessID:"<<p<<",EXEfile:"<<pe.sz<<",%inkernelmode:"<</消除句柄}bMore=::Process32Next(hSnapshot,&p}}程序1-4程序首先运用WindowsXP的新特性,即工具协助库来获得目前运行的所有进程的快照。然后应用程序进入快照中的每一种进程,得到其以PROCESSENTRY32构造表达的属性。这一构造用来向OpenProcessOAPI函数提供进程的ID。Windows跟踪每一进程的有关时间,示例中是通过打开的进程句柄和GetProcessTimesOAPI来直询得到有关时间的。接下来,一种定制的协助函数获得了几种返回的数值,然后计算进程在内核模式下消耗的时间占总时间的比例。程序的其他部分比较简朴,只是将有关信息显示给顾客,清除进程句柄,然后继续循环,直到所有进程都计算过为止。在“命令提醒符”窗口运行CLEXE,产生1-4.EXE文献:运行成果:西C:\Docuents运行成果:西C:\DocuentsandSettinga\AdiniatrProceoID:768.EXEfile:GmGE.oxe.*inkernelProceGID:900.EXEfile:vinlogon·oxe.*nkernelID:956:EXE_fle:LSAs1136.EXEfile:svohoot.exe.*inID:ID:4972EXEFID:6132.EXE*inkernel努部第二部分:进程的“毕生”Windows所创立的每个进程都从调用CreateProcessOAPI函数开始,该函数的任务是在对象管理器子系统内初始化进程对象。每一进程都以调用ExitProcess(或TerminatePocess()API函数终止。一般应用程序的框架负责调用ExitProcessO函数。对于C++运行库来说,这一调用发生在应用程序的mainO函数返回之后。本试验显示了创立子进程的基本框架。该程序创立的子进程仍然执行父进程的程序代码,显示它的系统进程ID和它在进程列表中的位置。创立子进程//proccreate项目(:sprintf(szCmdLine,"\"%s'//用于子进程的STARTUPINFO构造:ZeroMemory(reinterpret_cast<void*>(&si)si.cb=sizeof(si);BOOLbCreateOK=::CreatePNULL,/缺省的进程安全性NULL,NULL,/不继承句柄/使用新的控制台{)ntmainintargc,char*a/确定进程在列表中的位置(std::cout<<"ProcessID:"<<::GetCurrentProcessId0/检查与否有创立子进程的需要(std;cout<<"I'mgone...Bye-bye";)本程序展示的是一种简朴的使用CreateProcessOAPI函数的例子。首先形成简朴的命令行,提供目前的EXE文献的指定文献名和代表生成克隆进程的号码。大多数参数都可取缺省值,不过创立标志参数使用了:行为像一种子进程标志,指示新进程分派它自己的控制台,这使得运行示例程序时,在任务栏上产生许多活动标识。然后该克隆进程的创立措施关闭传递过来的句柄并返回mainO函数。在关闭程序之前,每一进程的执行主线程都会暂停等待输入字符,以便让顾客观测子进程的行为。CreateProcess)函数有5个关键参数?本试验程序中设置的各个参数的值的含义是:a.(LPCTSTRIpApplicatic.(BOOLblnheritHandles)FALSE,//不继承句柄:e.(LPPROCESS_INFORMATONIpProcessInformation)&pi);//返回的进程信息程序运行时屏幕显示的信息是:ProcessID:3344,CloneProcessID:3344,CloneI'ngone…Bye-byePre本试验的程序中列出了用于进程信息查询的API函数GetProcessVersion(与GetVersionEx(的共同作用,可确定运行进程的操作系统的版本号。{/提取这个进程的ID号DWORDdwdThis=::GetCurreWORDwMajorReq=(WORD)dwVerRWORDwMinorReq=(WORD)dwVerReq&0xfff);std::cout<<"Process<<",requiresOS"<<wMajorReq<<wMinorReq<<std//设置版本信息的数据构造,以便保留操作系统的版本信息osvix.dwOSVersionInfoSize=sizeoGetVersionEx(reinterpret_cast<LPOSVERSIONINFOstd::cout<<"RunningonOS:"<<osvix.dwMajorVersion<<"."<<osvix.dwMinorVersion<<std::eif(osvix.dwPlatformld==VER_PLATFORM_W(:GetCurrentProcess(),/运用这一进程/汇报给顾客std::cout<<"TaskManagershouldnownowindicat"processishighpriority."<<std:eProcessID:5436,requiresProcessID:5436,requires目前PID信息:5436目前操作系统版本:5.1系统提醒信息:TaskManagershouldnownowindicatethisprocessishighpriority程序向读者表明了怎样获得目前的PID和所需的进程版本信息。为了运行这一程序,系统处理了所有的版本不兼容问题。接着,程序演示了怎样使用GetVersionExOAPI函数来提取OSVERSIONINFOEX构造。这一数据块中包括了操作系统的版本信息。其中,“OS:5.1”表达目前运行的操作系统是:最终一段程序运用了操作系统的版本信息,以确认运行的是WindowsXP。代码接着将目前进程的优先级提高到比正常级别高。单击Crl+Alt+Del键,进入“Windows任务管理器”,在“应用程序”选项卡中右键单击本任务,在快捷菜单中选择“转到进程”命令。在“Windows任务管理器”的“进程”选项卡中,与本任务对应的进程映像名称是(为何?):右键单击该进程名,在快捷菜单中选择“设置优先级”命令,可以调整该进程的优先级,如设置为“高”后重新运行程序,屏幕显示有变化吗?没有指令其父进程来“杀掉”自己的子进程(//格式化用于子进程的命令行,指明它是一种EXE文献和子进程::sprintf(szCmdLine,//子进程的启动信息构造::ZeroMemory(reinterpret_cast<void*si.cb=sizeof(si);//应当是此构造的大小//返回的用于子进程的进程信息//用同样的可执行文献名和命令行创立进程,并指明它是一种子进程BOOLbCreateOK=::CreateProcess(NULL,NULL,NULL,NULL,//释放指向子进程的引用{{/创立“自杀”互斥程序体//产生的应用程序名称(本EXE文献)/告诉我们这是一种子进程的标志//用于进程的缺省的安全性/用于线程的缺省安全性/不继承句柄//创立新窗口,使输出更直观//新环境//目前目录/启动信息构造/1返回的进程信息HANDLEhMutexSuicide=::CreatNULL,{/缺省的安全性//最初拥有的/为其命名std::cout<<"Creatingthechildproc//指令子进程“杀”掉自身std::cout<<"Tellingthechildprocesstoquit."<<std::endl;//消除句柄}{/打开“自杀”互斥体HANDLEhMutexSuicide=::OpeSYNCHRONIZE,/打开用于同步FALSE,/不需要向下传递g_szMutexName);//名称{/汇报正在等待指令std::cout<<"Childwaitingforsuicideinst::WaitForSingleObject(hMutex//准备好终正,清除句柄std::cout<<"Childquiting."<<std::end;{//决定其行为是父进程还是子进程if(argc>1&&::strcmp(argv[l],"ch{{1程序阐明了一种进程从“生”到“死”的整个毕生。第一次执行时,它创立一种子进程,其行为如同“父亲”。在创立子进程之前,先创立一种互斥的内查对象,其行为对于子进程来说,如同一种“自杀弹”。当创立子进程时,就打开了互斥体并在其他线程中进行别的处理工作,同步等待着父进程使用ReleaseMutex)API发出“死亡”信号。然后用SleepOAPI调用来模拟父进程处理其他工作,等完毕时,指令子进程终止。当调用ExitProcessO时要小心,进程中的所有线程都被立即告知停止。在设计应用程序时,必须让主线程在正常的C++运行期关闭(这是由编译器提供的缺省行为)之后来调用这一函数。当它转向受信状态时,一般可创立一种每个活动线程都可等待和停止的终止事件。在正常的终止操作中,进程的每个工作线程都要终止,由主线程调用ExitProcesso。接着,管理层对进程增长的所有对象释放引用,并将用GetExitCodeProcess(建立的退出代码从STILL_ACTIVE变化为在ExitProcess(调用中返回的值。最终,主线程对象也如同进程对象同样转变为受信状态。等到所有打开的句柄都关闭之后,管理层的对象管理器才销毁进程对象自身。还没有一种函数可获得终止后的进程对象为其参数,从而使其“复活”。当进程对象引用一种终止了的对象时,有好几种API函数仍然是有用的。进程可使用退出代码将终止方式告知给调用GetExitCodeProcess0的其他进程。同步,GetProcessTimesOAPIGetProcessTimesOAPI函数可向主调者显示进程的终止时间。CreatingthechildproTellingthechildprocess请总结一下本次试验的收获、教训和感受,结合书本内容谈一下你对进程的理解。试验二并发与调度在本试验中,通过对事件和互斥体对象的理解,来加深对WindowsXP线程同步的理解。通过度析试验程序,理解管理事件对象的API。理解在进程中怎样使用事件对象,在进程中怎样使用互斥体对象,线程怎样通过文献映射对象发送数据。二、试验环境硬件环境:计算机一台,局域网环境;软件环境:WindowsXPProfessional,VisualC++6.0专业版或企业版。第一部分:互斥体对象本程序中显示的类CCountUpDown使用了一种互斥体来保证对两个线程间单一数值的访问。每个线程都企图获得控制权来变化该数值,然后将该数值写入输出流中。创立者实际上创立的是互斥体对象,计数措施执行等待并释放,为的是共同使用互斥体所需的资源(因而也就是共享资源)。1、运用互斥体保护共享资源//mutex项目{{m_hMutexValue=::CreateMNULL,//缺省的安全性TRUE,m_hThreadlnc=::CreateThNULL,//缺省的安全性IncThreadProc,//类线程进程reinterpret_cast<LPVOID>(this),//线程参数0,/无特殊的标志NULL);/忽视返回的idm_hThreadDec=::CreateThNULL,//缺省的安全性0,/缺省堆栈reinterpret_cast<LPVOID>(this),/线程参数0,NULL);//忽视返回的id}{}{{/等待两者完毕(次序并不重要)::WaitForSingleObject(m_h:WaitForSingleObject(m_hTvirtualvoidDoCount(/循环,直到所有的访问都结束为止{:WaitForSingleObject(m_hMu/变化并显示该值std:cout<<"thread:"<<::GetCur<<"access:"<<m_nAccess<<st_/释放对数值的访问}reinterpret_cast<CCountUpDown*>(lpPa}{reinterpret_cast<CCountUpDown*>(lpPaud.WaitForCompletio分析程序的运行成果,可以看到线程(加和减线程)的交替执行(由于SleepOAPI容许Windows切换线程)。在每次运行之后,数值应当返回初始值(0),由于在每次运行之后写入线程在等待队列中变成最终一种,内核保证它在其他线程工作时不会再运行。1)请描述运行成果(假如运行不成功,则也许的原因是什么?):两个线程交替运行,不停变化value两个线程交替运行,不停变化value的值。两个线程互斥访问Value的值hread:3820value:laccethread:5588value:Saccethread:3828value:1accethread:5588value:Baccethread:382ualue:1accethread:550lvalue:Saccethread:3028value:1accethread:558value:Raccthread:5588value:Saccethread:3828value:1accechread:5588value:Bathread:3828value:laccethread:55Bavalue:Baccetheread:3828value:1accethread:550lvalue:faccthread:3829value:laccthread:5508value:Bacthread:5508value:laccthread:5508value:Bathread:3828value:1acthread:550avalue:Baccthread:382lvalue:1acc线程1(5296)先运行,将value值增1,变为1。然后,线程2(6016)运行,将value值减1,变为0.献、文献映射、邮件位和命名管道等,其中最常用的是文献和文献映射。此类对象容许一种线程很轻易地向同一进程或其他进程中的另一线程发送信息。下边程序代码展示了线程怎样通过文献对象在永久存储介质上互相发送数据。程序只是激活并启动了一种线程接着一种线程的创立线程。每个线程从指定的文献中读取数据,并对数据进行修改,其修改增量是以创立时发送给它的数量进行的,然后将新数值写回文献。//要使用的文献名staticLPCTSTRg_sx="w//在数据文献中读取目前数据的简朴线程时将传递来的该数据增长,并写回数据文献中staticDWORDWINAPIThreadProc(LPVOIDlpParam){//将参数翻译为长整数LONGnAdd=reinterpret_cast<LONG>(p//建立完全的指定文献名(包括途径信息)::GetTempPath(MAX_PATH,szFllName);//获得途径//打开文献对象HANDLEhFile=::CreatszFulIName,//文献的完全名称GENERIC-READ|GENERIC_WRITE//具有所有的访问权/容许其他线程读取NULL./一般文献NULL);(/读取目前数据reinterpet_cast<LPVOID>(&nVa//缺省的安全性//创立或打开文献//无模板文献//要读取的文献//缓冲区NULL);//缓冲区容量//无重叠I/Ostd::cout<<"read:"<<nVal/增长数值/写回永久存储介质reinterpret_cast<LPCVOID>(&nVaNULL);if(dwXfer==sizeof(n{std::cout<<"write:"<<nVal/要写入的文献/写入的字节数/无重叠I/O/创立100个线程从文献中进行读写for(intnTotal=100;nTotal{/启动线程HANDLEhThread=::CreateNULL,reinterpret_cast<LPVOID>NULL);::WaitForSingleObje/缺省的堆栈/无特殊的创立标志/忽视线程id阅读和分析程序,请回答问题:1)程序中启动了多少个单独的读写线程?2)使用了哪个系统API函数来创立线程例程?3)文献的读和写操作分别使用了哪个API函数?每次运行进程时,都可看到程序中的每个线程从前面的线程中读取数据并将数据增长,文献中的数值持续增长。这个示例是很简朴的通讯机制。可将这一示例用作编写自己的文献读/写代码的模板。请注意程序中写入之前文献指针的重置。重置文献指针是必要的,由于该指针在读取结束时将处在前四个字节之后,同一指针还要用于向文献写入数据。假如函数向该处写入新数值,则下次进程运行时,只能读到本来的数值。那么:4)在程序中,重置文献指针使用了哪一种函数?5)从输出成果,对照分析程序,可以看出程序运行的流程吗?请简朴描述:首先创立一种线程,读nValue的值,然后nValue值加一后,将nValue值重新写入文献。反复上述过程1002、演示使用映射文献的内存互换数据的线程/仲裁访问的互斥体(HANDLEhMapping=reintarpret_cast<HANDLE>(I/等待对文献的访问:WaitForSingleObject(g_hMutexMLPVOIDpFile=:MapViewOfFile(0.//在文献的开头处(高32位开始{LONG*pnData=reinterpret_cast<LON/显示新数值std::cout<<“thread”<<::GetCu<<"value:"<<(*pnData)<<std释放文献视图(NULL,NULL);(LPVOIDpData=::MapView,//获得读写权数据文献//最大容量(高32位)HANDLEhMapping=::MakeSharedFileO);{0,/缺省堆栈{std::cout<<“allthreadscreated,waiting.”<<std:end;/关闭对象阅读和分析程序,请回答:1)程序中用来创立一种文献映射对象的系统API函数是哪个?2)在文献映射上创立和关闭文献视图分别使用了哪一种系统函数?3)运行时,程序首先通过(MakeSharedFileO;)函数创立一种小型的文献映射对象(hMapping),接着,使用系统API函数(CreateMutex();)再创立一种保护其应用的互斥体(g_hMutexMapping)。然后,应用程序创立100个线程,每个都容许进行同样的进程,即:通过互斥体获得访问权,这个操作是由语句:_WaitForSingleObject(g_hMutexMapping,INFINITE);实现的。再通过函数(MapVewOfFile(;)操作将视图映射到文献,将高32位看作有符号整数,将该数值增长(即命令:++(pnData);),再将新数值显示在控制台上。每个线程清除文献的视图并在退出之前释放互斥体的语句是ReleaseMutex(g_hMutexMapping);。当线程完毕时,应用程序关闭并退出。4)将程序中的语句::Sleep(500);删除(例如在语句前面加上“/”)后,重新编译运行,结变化吗?为何?有变化。100个线程一闪而过,不能看清成果。由于Sleep(500)是为了放慢速度,以便观测。请总结一下本次试验的收获、教训和感受,结合书本内容谈一下你对进程间控制的理解。通过这次试验,我对操作系统中的事件和互斥体对象,以及线程同步的概念有了更清晰的理解。当多种进程并发执行时,若我们不指定进程之间并发的次序,则他们可以任意并发,多种进程访问同一种互斥资源时,会出现错误,或者计算成果不唯一,这时我们必须通过某种手段来同步进程间并发的次序,这便是进程间的同步问题。并且,并发执行的进程或线程间,有时为了需要,会互相之间进行数据的互换,即进程间通信,Windows中,可以通过文献对象在线程间发送数据。还可以使用映射文献的内存互换数据。试验三存储管理一、试验目的通过试验理解WindowsXP内存的使用,学习怎样在应用程序中管理内存,体会Windows应用程序内存的简朴性和自我防护能力。学习检查虚拟内存空间或对其进行操作;理解WindowsXP的内存构造和虚拟内存的管理,进而理解进程堆和Windows为使用内存而提供的某些扩展功能。本试验中还以一种Linux实例程序阐明应用程序怎样通过系统调用来管理自己用的空闲内存,目的在于加深同学对操作系统存储管理内容的理解。二、试验环境硬件环境:计算机一台,局域网环境;软件环境:WindowsXPProfessional,LinuxRedhat9.0或Ubumtu,VisualC++6.0专业版或企业版。三、试验内容和环节在WindowsXP环境下,4GB的虚拟地址空间被划提成两个部分:低端2GB提供应进程使用,高端2GB提供应系统使用。这意味着顾客的应用程序代码,包括DLL以及进程使用的多种数据等,都装在顾客进程地址空间内(低端2GB)。//工程vmwalker#pragmacomment(lib,{return((dwTarget&dwMask)==dwMa#defineSHOWMASK(dwTarget,if(TestSet(dwTarget,PAGEvoidShowProtetion(DWORDdwTa{{/首先,获得系统信息{//缓冲区/大小确实认{LPCVOIDpEnd=(PBYTE)pBlock+mbi.Reg:StrFormatByteSize(mbi.RegionSi<<std:hex<<std::setw(8)<<(DWORD)pB<<std:hex<<std::setw(8)<<(DWO<<(::strlen(szSize)==7?"(":"(")<<szSi/显示块的状态if(mbi.Protect==0&&mbi.Sate!=1/除去途径并显示)/完全指定的文献名称一}C:\PrograxFilea\lierosoC:\PrograxFilea\lieroso77fcf090-77fd1880(8.00K77fd1800-7c880000(72.1MB>FreeHOAZc884088-7c887888<12.8KB>Comnitted.READVRITE.2c887808-7c889889(8.00KR>Comnittad.VRITECOPy.InageZc889000-7c91d⁸e⁰(592KB)Co2c⁹1de⁰0-7c⁹20008(127c9288e-7c⁹218ea(4.38KB)Comsitted,READONLY.Inage.Hodule:ntd11.d117c9218N⁰-7c99c888<588KB>Conmitt2c996888-7c9a1889(12.8KB>Connitted.REA209a1000-7c9.3880(8.00KB>Comitted.WRITECOPy.Inage2e943008-7e⁹b6808(76.0KB>Connitted,HEADONLY,Inage7c9b⁶0N⁸-76F0899(45.2HB716F88B⁸-7F6F788a<28.8KB>Committed.EXECUTE16f⁷800-7F7F00en(996KB)Renerved.READONLY.HappZff0000-7fd3009(204KB>ConmittedREADONLY,HappedZFFd3888-7TFdc888(36.8KZKfdc098-7Efdd⁸e⁸(4.88KB)Comnitted.READVRITE,2ffdd⁹80-7ffdf889(8.00KB>Freo.NOACZffdf⁸00-7Ffo⁰009(4.00KB>Comnftted.READVRITE.PelvateZffeB⁰08-7FF=1080(4.00KB>Connitted.HEADONLY.rfe¹88-7Tffuen(68.0KB>Reserved,NOACCENs,Private内存的特性。虚拟内存中的块由VirtualQueryExOAPI定义成持续快或具有相似状态(自由区、已调配区等等)的内存,并分派以一组统一的保护标志(只读、可执行等等)。分析运行成果按committed、reserved、free等三种虚拟地址空间分别记录试验数据。其中“描述”是指对该组数据的简朴描述,例如,对下列一组数据:00010000-0001<8.00KB>Committed,READWRI可描述为:具有READWRITE权限的已调配私有内存区。将系统目前的自由区(free)虚拟地址空间填入表中。大小空间类型将系统目前的已调配区(committed)大小空间类型将系统目前的保留区(reserved)虚拟地址空间填入表5-8大小空间类型2.虚拟内存操作使用。{BYTE*arFill=(BYTE*)for(DWORDdwFill=0;dwFill<dwSiz{std:cout<<"Memoryzeroadl"<<std:endl;std:cout<<"Couldnotzerom}/使用内存分派来获得1GB块{LPVOIDpBlock=:malloc(c_dwGiNULL,c_dwGigabyte,/规定IGBMEM_COMMIT,/调配物理存储PAGE_READWRITE);/对此的读写1 LPVOIDpBlock=::VrtuaNULL,/不指定起始地址c_dwGigabyte,//规定1GBMEM_RESERVE,/不调配物理存储PAGE_READWRITE);/对此的读写LPVOIDpBlock=:VrtuaNULL,MEM_RESERVE,/不调配物理存储PAGE_READWRITE);/对此的读写操作C:VProerFilcs\WicrosoftYisuslStudio\yProjceta\IIWebug\11.exoemoryzeroed对照运行成果,分析程序。为了给数据库保留1GB的段地址空间,程序给出了内存分派的四种措施。即程序中阐明为使用内存分派来获得1GB块的程序段,该段程序试图运用原则C中的malloc0函数,从已经已调配的小内存区获得内存。从运行成果看,这种技术成功了吗?没有成功·第二种技术即程序中阐明为使用虚拟分派来获取物理1GB块的程序段,该段程序试图通过VirtualAllocO,然后运用物理备用内存将整个块分派到虚拟内存空间的任何位置。这种技术只对拥有1GB以上的RAM且均有换页文献的计算机可行。从运行成果看,这种技术成功了吗?没有成功·第三种技术即程序中阐明为使用虚拟分派来获取虚拟1GB块的程序段,该段程序运用VirtualAllocO,假如函数成功,则获得大块内存,但不将任何物理内存调配到此块中。从运行成果看,这种技术成功了吗?没有成功·第四种技术即程序中阐明为使用虚拟分派调配来获取虚拟1GB块,再为其调配1MB物理存储的程序段,该段程序保留IGB的内存区,然后将物理内存调配给其中的很小一部分(1MB)。这就是程序简介的处理一种假想的数据库应用程序的措施:保留整个块,然后按规定在其一小部分内进行读操作,让系统将用过的区域换页到磁盘中。运用VirtualLock0API,Windows可用来在自己的进程空间中控制虚拟内存的行为。这个函数与其成对的VirtualUnlockO制止或容许一块内存从物理RAM中换页和换页到页面文献中。这样就会告知系统有一段特定的内存区规定对顾客作出强烈的响应,因此系统不应将其移出RAM。当然,假如要将整个虚拟内存空间锁定,系统就会停留于试图将系统中工作内存的每一小块换页到磁盘3.虚拟内存的分派与释放能对的使用系统函数GetMeoryStatus0和数据构造MEMORY_STATUS理解系统内存和虚拟存储空间使用状况,会使用VirsualAlloc()函数和VirsualFree()函数分派和释放虚拟内存空间。//GetMemoryStatus.cpp:Definestheentrypointforthe#include"GetMemorySt#endifint_tmain(intargc,TCHAR*argv).TCHAR{printf("NowAllocate32MVrsualMemoryaBaseAddr=:VirtualAlloc(NULL,1024*1024*32,MEM_RESERVEMEM_COMMIT,PAGE;//分派虚拟内存if(BaseAddr==NULL)printf("VirsualAllocateFail.\n");str=(char*)malloc(1printf("NowRelease32MVirsif(:VirtualFree(BaseAddr,0,MEM_RELEASE)==0)/printf("ReleaseAllocateFail\n");free(str);}{printf("\tTotalPhysicalMemoryis%dMB\n",Memlnfoprintf("\tAvailablePhysicalMemoryis%dMB\n",Memlnfo.dprintf("\tTotalPage%dMB\n",Memlnfo.dwTotalPaprintf("\tAvailablePage%dMB\n",Memlnfo.dwAvailPageFile/(1024*1024));printf("\tTotalVirtualMemoryis%dMB\n",Memlnfo.dwprintf("\tAvailableVirsualmemoryis%dMB\n",Memlnfo.dwAvailVirtprintf("\tMemoryLoadis%d%%\n\n"}环节1:在VC6.0环境下选择Wn32ConsoleApplication建立一种控制台工程文献,选择Anapplication环节2:编辑并编译完毕后,单击“Build”菜单中的“BuildGetMemoryStatus.exe”命令,建立GetMemoryStatus.exe可执行文献。操作能否正常进行?假如不行,则也许的原因是什么?可以正常运行环节3:在工具栏单击“ExecuteProgram”按钮,执行GetMemoryStatus.cpp.exe程序。分析程序GetMemoryStatus.cpp的运行成果1)请描述运行成果(假如运行不成功,则也许的原因是什么?):AvailablePhysicalHenoTotalUirtualHemoryHouRelease32MVirsualMemoryand2MPhysiTotalUirtualHemory2)根据运行输出成果,若要变化分派和回收的虚拟内存和物理内存的大小,要变化程序代码的语句,分别为BaseAddr=:VirtualAlloc(NULL,1024*1024*32,MEM_RESERVEMEM_COMMIWRITE);//分派虚拟内存if(BaseAddr==NULL)printf("VirsualAllocateFail.\n");printf("NowRelease32MVif(::VirtualFree(BaseAddr,0,MEM_RELEASE)==0)printf("ReleaseAllocateFail.\n");free(str);3)根据运行输出成果,对照分析4-2程序,可以看出程序运行的流程吗?请简朴描述:第二部分Linux顾客程序的内存管理现代操作系统容许多种程序同步运行,因此,内存中需要同步寄存这些程序。操作系统采用的存储管理方案重要有分区式存储管理、分页式存储管理、分段式存储管理和段页式存储管理等。本试验以一种Linux实例程序阐明应用程序怎样通过系统调用来管理自己用的空闲内存,目的在于理解顾客程序分派内存以及回收所用内存的程序过程,加深对操作系统存储管理机制的理解。本试验实例由my-malloc.h、my-malloc.c和test.c三个文献构成。为阅读程序以便,对其中的重要函数作了阐明,同学们可结合程序注释理解该程序。本试验程序重要定义了一种描述自由存储块的构造,每一种自由块都包括块的大小、指向下一块的指针以及块区自身,所有的自由块以地址增长次序排列,并用链表链接起来。这一链表是本程序维护的一种空闲区域,对于操作系统的目前记录来说是已分出去的区域。由于本程序是运行在顾客态的程序。环节1:单击红帽子,在“GNOME协助”菜单中单击“附件”-“文本编辑器”命令,在文本编辑中键入清单5-4程序并保留为my-malloc.h。清单5-4my-malloc.h文献/*foralignmenttolongboundar/*nextblockifonFreelist*//*sizeofthisblock*//*forcealignmentofblocks*/#defineNALLOC10/*minimum#unitstorequestaticHeader*morecore(unsvoid*Malloc(unsignedstaticHeaderbase;/#empylistaticHeader*free_list=NULL;/*startoffr/*Malloc:general-purposestorageallocator*/void*Malloc(unsignedintnbytes){nunits=(nbytes+sizeof(Header)-1)/sizeof(Headif((prev=free_list)==NULL){/*nofreelistyet*/base.s.next=free_list=prev=&b}for(p=prev->s.next;;prev=p,pif(p->s.size>=nunits){/*bigenough*/if(p>s.size==nunits)prev->s.next=p>s.neif((p=morecore(nunits}staticHeader*morecore(unprintf("sbrk:%X-%X\n",cp,cp+nu*sizof(Header));if(cp==(char*)-1)}bp=(Header*)ap-1;/*pointtoblockheader*/for(p=free_list;!(bp>p&&bp<p>s.nextif(p>=p->s.next&&(bp>plbp<pbreak;if(bp+bp->s.size==p->s.next){/*jointouppernbr*/bp->s.size+=p>s.next->s.sbp->s.next=p->s.next->s.neif(p+p>s.size==bp){}}printf("base:%X,base.next:%X,base.next,next:%X,free:%x\n",&base.s.next,base.s.next->s.next,free_lifor(p=&base;p->s.next!=free_lprintf("block%d,size=%d",I,p->s.si}p[i]=(char*)Malloc(printf(“malloc%d,%X\n”,i,p[i}printf("free%d\n",i}环节4:编译。成功解。试验四输入输出管理程序中捕捉鼠标,从而加深理解WindowsXP输入/输出处理技术。在本试验中,着重理解磁盘的物理组织,以及怎样通过顾客态的程序直接调用磁盘VOAPI函数(DeviceloControl)根据输入的驱动器号读取驱动器中磁盘的基本信息。硬件环境:计算机一台,局域网环境:软件环境:WindowsXPProfessional,LinuxRedhat9.0或Ubumtu,VisualC++6.0专业版或企业版。三、试验内容和环节一台计算机拥有大量的输入设备,而鼠标和键盘是其中最常用的输入设备盘处理就像使用VisualC++的ClassWizard在MFC程序中添加一两个消息响应函数同样简朴。在本试验中,我们通过一种应用程序示例来讨论鼠标编程技巧,理解怎样响应鼠标程序中捕捉鼠标。该程序的实例代码在试验指导书外另附。环节2:在“开始”菜单中单击“程序”“MicrosoftVisualStudio6.0”-“MicrosoftVisualC++6.0”环节3:在File菜单单击OpenWorkspace.…命令,在“OpenWorkspace”对话框中找到试验代码文献夹并打开试验文献Mouse.dsw。环节4:单击Build菜单中的BuildMouse.exe命令,系统对程序进行编译并建立可执行文献。操作能否正常进行?假如不行,则也许的原因是什么?可以正常运行环节5:在工具栏单击“ExecuteProgram”按钮,执行Mouse.exe程序,响应鼠标消息。Mouse示例程序演示了怎样截取和响应鼠标消息。运行这个程序,就会显示一种主窗口。最初窗口是在鼠标通过窗口时单击鼠标左键,窗口中不仅出现WM_LBUTTONDOWN和WM_LBUTTONUP消息,并且显示事件发生的坐标。单击鼠标右键,再次出现上述状况。请记录:Y:164:鼠标移动到指定位置:单击鼠标左键:释放鼠标左键:单击鼠标右键:释放鼠标右键Mouse应用程序也举例阐明了鼠标捕捉的技巧。有些时候需要应用程序接受鼠标消息,甚至鼠标不在应用程序客户区时,也有这个规定。例如在一种画图程序中,顾客在窗口中画线时一直接住鼠标左键。假如一种顾客碰巧把鼠标指针移到画图应用程序的窗口之外,应用程序必须继续接受鼠标消息。否则顾客在窗口之外释放鼠标按钮,应用程序将无法懂得顾客与否仍旧在画图。为理解鼠标捕捉的工作状况,可把指针移动到Mouse应用程序的客户区,然后一直按住鼠标右键,在屏幕上任意移动鼠标。虽然鼠标移动到窗口外,窗口继续接受鼠标消息。在不按住鼠标右键移动鼠标时,鼠标指针离开了应用程序的客户区的状况下,应用程序停止接受鼠标消息。注意到,在按住鼠标右键移动到客户区外面左侧时,WM_MOUSEMOVE的坐标值目前为负的。这是由于何?超过客户区域后为负值环节7:测试Mouse应用程序由于在窗口的视图类CMouseView中定义了消息响应函数,Mouse应用程序会响应鼠标消息。作为MFC编程的一条规则,CMouseVew使用消息映射把消息和消息响应函数联络起来。下面的代码显示CMouseVew类怎样定义它的消息映射。每一种包括消息映射体的宏把鼠标消息和合适的消息处理程序有关联。例如,当窗口接受WM_MOUSEMOVE消息时,ON_WMMOUSEMOVE宏告知MFC调用OnMouseMove(O函数。同样,当窗口接受WM_LBUTTONDOWN消息时,消息映射告知MFC调用OnLButtonDownO函数。出目前Mouse应用程序窗口的文本由视图类消息响应函数来显示。例如,下列代码显示了OnMouseMove()函数:(wsprintf(str,"X:%dY:%d",!在鼠标指针移动到应用程序窗口时,Mouse应用程序接受这些消息流。作为函数的第二个参数传送的CPoint对象包括了在事件发生时鼠标指针所在位置的信息。OnMouseMove从CPoint对象中建立一种显示的字符串,并且在应用程序的窗口中显示这个字符串。OnLButtonDownO、OnLButtonUpO、OnLButtonDbIClkO和OnRButtonDbIClkO函数工作状况相似,把CPoint对象转变为在应用程序窗口中显示的显示字符串。环节8:读懂WindowsXP获取鼠标消息的函数以及对事件处理的代码,在此基础上修改原程序段,产生新的响应事件:1)修改鼠标左键单击后的事件,使在单击鼠标后,在单击的位置上出现“你好”字样。2)修改鼠标右键单击释放的事件,使在单击鼠标按下的位置出现“再”字,在释放右键的位置上出现“见”字。操作与否成功?假如不行,则也许的原因是什么?可运行成功见再环节9:单击窗口右上角的“关闭”按钮,结束第二部分磁盘I/0API函数应用背景知识有关的API简介LPVOIDlplnBuffer,DWORDnlnBufferSize,LPVOID1pOutBuffer,DWORDnOutBufferSiz.nInBufferSize:指定1pInBustructDISK_GEOMETRY(unsignedbytesPerSector;unsignedsectorsPerTrack;unsignedheads;unsignedcylindHANDLECreateFile(LPCTSDWORDdwShareMode,LPSECURITY_ATTRIBUTDWORDdwCreationDisposition,此参数可认为下列值的任意一种组合值:.0:指定对象的查询访问权限,一种应用程序可以不通过访问设备来查询设备属性。.dwCreationDisposition:指定对存在的文献采用哪种措施,且当文献不存在时采用哪种措施,此函数必须是下列值中的一种:.CREAT_NEW:创立一种新文献,假如文献存在,则函数调用失败。.OPEN_EXISTING:打开文献,假如文献不.TRUNCATE_EXISTING:打开文献,一旦文献打开,就被删截掉,从而使文.dwFlagsAndAttributes:指定文献属性和标志,该参数可取诸多种组合,如下示三种:指定事件被设置为发信号状态。.:引导系统打开没有瞬间缓冲或缓存的文献,当与结合时,标志给出最大的准时间次序的操作,由于I/0不依托内存管理器的时间次序的操作,不过,由于数据没有在缓存中,某些I/0操作将长某些。.:表明文献从开头到结尾按次序被访问。使用它,系统可优化文献缓存。访问方式读大文献的应用程序,指定此标志可以增长它的性能。返回值:假如函数调用成功,返回值为指向指定文献的打开句柄:假如函数调用失败,返回值为试验目的本试验着重于理解磁盘的物理组织,以及怎样通过顾客态的程序直接调用磁盘VOAPI函数(DeviceIoControl)根据输入的驱动器号读取驱动器中磁盘的基本信息,在WindowsXP环境进行。structDisk//有关Dis{voidmain(void){disk=physicDisk(Driv}{I,//共享的权限{}Result=DeviceloControl(NULL{}程序的成果aa盘所在磁盘总共有2880个扇区f盘有:如输入磁盘号为c,显示的磁盘信息是整个硬盘信息,而不是c盘分区的信息。如输入磁盘号为d,显示的磁盘信息与如输入磁盘号为c显示的磁盘信息相似。用磁盘I/0API函数读出的磁盘信息是从硬盘的主引导区得到。让扬声器按指定的长度和音频发声#defineDEFAULT_LEN/默认不反复发声/同样以微秒为单位/发声长度,以微秒为单位反复的次数/打印协助信息并退出{printfcUsage:nt%s[-ffrequency][-Ilength][-rreps][-ddelay]\n",executable_}{(intfreq=atoi((++if((freq<=0)|(freq>fprintf(stderr,"Badparameter:frequ/发声的时间长度fprintf(stderr,"Badparameterlengthmustbe>=0'n");if((console_fd=open("/dev/console",0_WRON[fprintf(stderr,"Failedtoopenconsole.n");/真正开始让扬声器发声(usleep(1000*parms.length);Ⅱ等ioctl(console_fd,KIOCSOUND,0);停止发声usleep(1000*pams.delay);/等待…/反复播放)运行成果(假如运行不成功,则也许的原因是什么?):发出了一种MI音,发音时长1秒,发了一次,隔了5秒发出的合适调整参数的值,看看声音有何变化。把-1的参数翻了一倍,-r的参数翻了2倍,发出了一种mi音,发音时长为2秒,发了4次,每隔5秒四、试验总结试验五文献系统录。三、试验内容和环节1.文献信息命令环节1:开机,登录进入GNOME。环节2:访问命令行。环节3:使用控制字符执行特殊功能。Crl+D:表达文献的末尾或者退出。Crl+D用于退出某些Linux工具程序(be、write等),退出一1)在shell提醒符下键入be,启动基本的计算器工具程序。2)把两个数字相乘(键入:458*594,然后按回车键)。当使用计算器的时候,你的提醒符是什么?Copyright1991-1994,1997,1998,,,FreeSoftwareFounda·一种擦除决定不执行的命令行的快捷方式。·假如登录到一种远程系统,退格键不起作用。·它可以保证在登录的时候,从一种“空”的顾客帐号和口令输入开始。·由于在口令输入的时候看不见它们,当懂得自己键入了错误字符的时候,使用Crl+U擦除密码,重新开始输入。假如输入一种命令,如Is-R/,有时候,会在按下回车键之前想擦除命令行。输入一种命令,在接下回车键执行命令之前按下Crl+U。成果是什么?输入的命令被消除了环节4:使用file命令确定文献类型。在Linux系统中可以找到许多类型的文献。文献类型可以通过使用file命令来确定。当一种顾客试图打开或阅读一种文献的时候,这个信息很重要。确定文献类型可以协助一种顾客决定使用哪个程序或命令来打开这个文献。这个命令的输出最常见的是如下几种:文本文献、可执行文献或数据文献。1)文本文献:包括ASCII或英语文本、命令文本和可执行的shell脚本。这种类型的文献可以使用cat或more命令读取,可以使用vi或其他文本编辑器编辑。单击红帽子,在“GNOME协助”菜单中单击“辅助设施”-“TextEditor”命

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论