操作系统实验指导书.doc_第1页
操作系统实验指导书.doc_第2页
操作系统实验指导书.doc_第3页
操作系统实验指导书.doc_第4页
操作系统实验指导书.doc_第5页
已阅读5页,还剩18页未读 继续免费阅读

下载本文档

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

文档简介

操作系统教程实验指导书编写者:吴 薇2014年8月20日目 录实验一 进程管理实验二 进程的同步和通信实验三 进程调度与死锁银行家算法实验四 存储器管理实验五 文件管理实验一 进程管理一、实验目的及要求 1、通过在Windows任务管理器中对程序进程进行响应的管理操作,熟悉操作系统进程管理的概念,学习观察操作系统运行的动态性能。2、通过Windows下的API函数创建进程,终止进程,进一步熟悉操作系统的进程概念。3、通过阅读和分析实验程序,学习创建进程、观察进程和终止进程的程序设计方法。二、实验设备(环境)及要求 一台运行Windows操作系统并安装了VC+的计算机。三、实验内容与步骤 1、使用任务管理器对程序进程进行管理操作。启动并进入Windows环境,单击Ctrl+Alt+Del键,或者右键单击任务栏,在快捷菜单中单击“任务管理器”命令,打开“任务管理器”窗口。回答以下几个问题:(1)当前机器中正在运行的应用程序有几个?(2)windows“任务管理器”的窗口由几个选项卡组成?当前有几个进程正在运行?(3)终止某进程后的操作结果如何?(4)试着给某进程设置优先级,看看它运行有什么改变?2、通过Windows下的API函数创建进程,终止进程。Windows所创建的每个进程都从调用CreateProcess()API函数开始,该函数的任务是在对象管理器子系统内初始化进程对象。每一进程都以调用ExitProcess()或TerminateProcess()API函数终止。通常应用程序的框架负责调用ExitProcess()函数。对于C+运行库来说,这一调用发生在应用程序的main()函数返回之后。步骤1:打开VC+窗口,新建Win32 Console Application项目,命名为createprocess,再新建一个C+ source file ”createprocess.cpp”,将附1的代码复制到文件中。步骤2:编译,链接,运行“createprocess.exe”程序。/也可“运行”-cmd,敲“createprocess.exe”运行。运行完后打开“任务管理器”查看当前程序所占用的内存。注意:CreateProcess()创建进程时使用的参数是CREATE_NEW_CONSOLE, / 使用新的控制台,指示新进程分配自己的控制台,这使运行程序时,在任务栏上产生许多活动标记,然后该克隆进程的创建方法关闭传递过来的句柄并返回main()函数。在关闭程序之前,每一个进程的执行主线程暂停了一下,以便让用户看到其中至少一个窗口。程序运行完后回答以下几个问题:1、CreateProcess()函数有几个核心参数?本实验程序中各参数值是什么?2、按下ctrl+alt+del,调用windows的任务管理器后,该进程相关的行为属性是什么?比如:PID、句柄数、内存使用情况、页面错误数、页面缓存大小等。步骤3:按步骤1新建一个c+源文件,命名为“getinformation.cpp”,将附2的代码复制至该文件,查看进程信息和当前运行进程的操作系统版本号。说明:Windows API中有两个函数可以得到系统版本信息GetVersion/ GetVersionEx 函数原型:BOOLGetVersionEx(POSVERSIONINFO pVersionInformation);OSVERSIONINFOEX这个结构:typedef struct DWORD dwOSVersionInfoSize;/在使用GetVersionEx之前要将此初始化为结构的大小DWORD dwMajorVersion; /系统主版本号DWORD dwMinorVersion; /系统次版本号DWORD dwBuildNumber; /系统构建号DWORD dwPlatformId; /系统支持的平台TCHAR szCSDVersion128; /系统补丁包的名称WORD wServicePackMajor; /系统补丁包的主版本WORD wServicePackMinor; /系统补丁包的次版本WORD wSuiteMask; /标识系统上的程序组BYTE wProductType; /标识系统类型BYTE wReserved; /保留,未使用 OSVERSIONINFOEX, *POSVERSIONINFOEX;在调用函数之前先初始化结构的大小:OSVERSIONINFOEX os;os.dwOSVersionInfoSize=sizeof(os);函数返回值为TRUE表示成功:if(!GetVersionEx(OSVERSIONINFO *)&os) return FALSE;函数调用成功以后就可以通过OSVERSIONINFOEX来查看系统的版本信息了。程序运行完后回答以下几个问题:1、该任务对应的进程映像名称是什么?你看到的进程号和操作系统版本是什么?2、如果调整该进程的优先级,比如设置为“高”后重新运行getinformation.exe,则屏幕显示有变化吗?为什么?步骤4:按步骤1新建一个c+源文件,命名为“killprocess.cpp”,将附3的代码复制至该文件,程序调试运行后将先创建一个子进程,然后指令子进程来“杀掉”自己的父进程,即终止自身运行。说明:程序说明了一个进程从“生”到“死”的整个一生。第一次执行时,它创建一个子进程,其行为如同“父亲”。在创建子进程之前,先创建一个互斥的内核对象,其行为对于子进程来说,如同一个“自杀弹”。当创建子进程时,就打开了互斥体并在其他线程中进行别的处理工作,同时等待着父进程使用ReleaseMutex()API发出“死亡”信号。然后用Sleep()API调用来模拟父进程处理其他工作,等完成时,指令子进程终止。当调用ExitProcess()时要小心,进程中的所有线程都被立刻通知停止。在设计应用程序时,必须让主线程在正常的C+运行期关闭(这是由编译器提供的缺省行为)之后来调用这一函数。当它转向受信状态时,通常可创建一个每个活动线程都可等待和停止的终止事件。在正常的终止操作中,进程的每个工作线程都要终止,由主线程调用ExitProcess()。接着,管理层对进程增加的所有对象释放引用,并将用GetExitCodeProcess()建立的退出代码从STILL_ACTIVE改变为在ExitProcess()调用中返回的值。最后,主线程对象也如同进程对象一样转变为受信状态。等到所有打开的句柄都关闭之后,管理层的对象管理器才销毁进程对象本身。还没有一种函数可取得终止后的进程对象为其参数,从而使其“复活”。当进程对象引用一个终止了的对象时,有好几个API函数仍然是有用的。进程可使用退出代码将终止方式通知给调用GetExitCodeProcess()的其他进程。同时,GetProcessTimes()API函数可向主调者显示进程的终止时间。请回答:程序运行过程你发现了什么现象?附1:Createprocess.cpp /创建子进程# include # include # include using namespace std; / 创建传递过来的进程的克隆过程并赋于其ID值 void StartClone(int nCloneID) / 提取用于当前可执行文件的文件名 TCHAR szFilenameMAX_PATH;: GetModuleFileName(NULL, szFilename, MAX_PATH); / 格式化用于子进程的命令行并通知其EXE文件名和克隆ID TCHAR szCmdLineMAX_PATH; : sprintf(szCmdLine, %s %d, szFilename, nCloneID); / 用于子进程的STARTUPINFO结构 STARTUPINFO si; : ZeroMemory(reinterpret_cast (&si) , sizeof(si) );si.cb = sizeof(si); / 必须是本结构的大小 / 返回的用于子进程的进程信息 PROCESS_INFORMATION pi; / 利用同样的可执行文件和命令行创建进程,并赋于其子进程的性质 BOOL bCreateOK = : CreateProcess(szFilename, / 产生这个EXE的应用程序的名称 szCmdLine, / 告诉其行为像一个子进程的标志 NULL, / 缺省的进程安全性 NULL, / 缺省的线程安全性FALSE, / 不继承句柄CREATE_NEW_CONSOLE, / 使用新的控制台NULL, / 新的环境NULL, / 当前目录&si, / 启动信息&pi); / 返回的进程信息 / 对子进程释放引用 if (bCreateOK) : CloseHandle(pi.hProcess); : CloseHandle(pi.hThread); int main(int argc, char* argv ) / 确定进程在列表中的位置 int nClone(0); if (argc 1) / 从第二个参数中提取克隆ID : sscanf(argv1 , %d , &nClone); / 显示进程位置 cout Process ID: : GetCurrentProcessId() , Clone ID: nCloneendl; / 检查是否有创建子进程的需要 const int c_nCloneMax =5; if (nClone C_nCloneMax) / 发送新进程的命令行和克隆号 StartClone(+nClone); / 在终止之前暂停一下 (0.5秒) : Sleep(500) ; system(PAUSE); return 0; 附2:getinformation.cpp /读取进程信息和操作系统版本# include # include void main() / 提取这个进程的ID号 DWORD dwIdThis =: GetCurrentProcessId(); / 获得这一进程和报告所需的版本,也可以发送0以便指明这一进程 DWORD dwVerReq = : GetProcessVersion(dwIdThis); WORD wMajorReq = (WORD) (dwVerReq 16); WORD wMinorReq = (WORD)(dwVerReq & 0xffff) ; std:coutProcess ID: dwIdThis , requires OS: wMajorReq wMinorReq std : endl ; / 设置版本信息的数据结构,以便保存操作系统的版本信息 OSVERSIONINFOEX osvix; : ZeroMemory(&osvix, sizeof(osvix) ) ; osvix.dwOSVersionInfoSize = sizeof(osvix); / 提取版本信息和报告 : GetVersionEx(reinterpret_cast (&osvix) ) ; std : cout Running on OS: osvix.dwMajorVersion . osvix.dwMinorVersion =5) / 改变优先级 : SetPriorityClass( : GetCurrentProcess(), / 利用这一进程 HIGH_PRIORITY_CLASS) ; / 改变为high / 报告给用户 std : cout Task Manager should now indicate this process is high priority std : endl; 附3: killprocess.cpp /父子进程的简单通信及终止进程# include # include # include static LPCTSTR g_szMutexName = w2kdg.ProcTerm.mutex.Suicide ; / 创建当前进程的克隆进程的简单方法 void StartClone() / 提取当前可执行文件的文件名 TCHAR szFilename MAX_PATH ; : GetModuleFileName(NULL, szFilename, MAX_PATH); / 格式化用于子进程的命令行,指明它是一个EXE文件和子进程 TCHAR szCmdLineMAX_PATH ; : sprintf(szCmdLine, %schild , szFilename) ; / 子进程的启动信息结构 STARTUPINFO si; : ZeroMemory(reinterpret_cast (&si) , sizeof(si) ); si.cb = sizeof(si) ; / 此结构的大小 / 返回的用于子进程的进程信息 PROCESS_INFORMATION pi; / 用同样的可执行文件名和命令行创建进程,并指明它是一个子进程 BOOL bCreateOK = : CreateProcess( szFilename, / 产生的应用程序名称 (本EXE文件) szCmdLine, / 告诉我们这是一个子进程的标志 NULL, / 用于进程的缺省的安全性 NULL, / 用于线程的缺省安全性 FALSE, / 不继承句柄 CREATE_NEW_CONSOLE, / 创建新窗口,使输出更直观 NULL, / 新环境 NULL, / 当前目录 &si, / 启动信息结构 &pi ); / 返回的进程信息 / 释放指向子进程的引用 if (bCreateOK) : CloseHandle(pi.hProcess) ; : CloseHandle(pi.hThread) ; void Parent() / 创建自杀互斥程序体 HANDLE hMutexSuicide = : CreateMutex( NULL, / 缺省的安全性 TRUE, / 最初拥有的 g_szMutexName); / 为其命名 if (hMutexSuicide != NULL) / 创建子进程 std : cout Creating the child process. std : endl; : StartClone(); / 暂停 5秒 : Sleep(5000); / 指令子进程杀掉自身 std : cout Telling the child process to quit. std : endl; : ReleaseMutex(hMutexSuicide); / 消除句柄 : CloseHandle(hMutexSuicide) ; void Child() / 打开自杀互斥体 HANDLE hMutexSuicide = : OpenMutex( SYNCHRONIZE, / 打开用于同步 FALSE, / 不需要向下传递 g_szMutexName) ; / 名称 if (hMutexSuicide != NULL) / 报告正在等待指令 std : cout Child waiting for suicide instructions. std : endl; : WaitForSingleObject(hMutexSuicide, INFINITE) ; / 准备好终止,清除句柄 std : cout Child quiting. 1 & :strcmp(argv1,child )=0) Child() ; else Parent() ; return 0; 实验二 进程的同步和通信一、 实验目的及要求1、掌握在linux操作系统环境上编辑、编译、调试、运行一个C语言程序的全过程。2、掌握进程并发执行的原理,理解进程并发执行的特点,区分进程并发执行与串行执行。3、了解linux中的信号,熟悉linux系统中进程之间软中断信号的基本原理。4、熟悉支持消息通信机制及消息量机制;了解Linux系统的进程间通信机构(IPC);理解Linux关于消息队列的概念;掌握Linux支持消息队列的系统调用。二、实验设备(环境)及要求 一台运行linux操作系统并安装了C编译器的计算机。三、实验内容与步骤 (1)练习使用linux操作系统环境。1、熟悉开机后登录linux系统和退出系统。2、练习常用命令如ls、ps、cd 、cp、rm、kill等。3、掌握一种编辑器,如gcc。(2)在linux操作系统下创建进程。1、编写一C语言程序,实现在程序运行时通过系统调用fork()创建两个子进程,使父、子三进程并发执行,父亲进程执行时屏幕显示“parent”,儿子进程执行时显示”son”,女儿进程执行时显示”daughter“。2、多次连续反复运行这个程序,观察屏幕显示结果的顺序,直至出现不一样的情况为止。记下这种情况,试简单分析其原因。3、修改程序,在父、子进程中分别使用wait,exit等系统调实现其同步推进,多次反复运行改进后的程序,观察并记录运行结果。(3)利用软中断通信实现进程同步的机制。1、编写程序:用fork()创建两个子进程,再用系统调用signal()让父进程捕捉键盘上来的中断信号(按c 键);捕捉到中断信号后,父进程用系统调用kill()向两个子进程发出信号,子进程捕捉到信号后分别输出下列信息,然后终止: child process1 is killed by parent! child process2 is killed by parent! 父进程等待两个子进程终止后,输出如下的信息后终止: parent process is killed!(4)实现并发进程间消息的发送与接收。1、编制两个程序client.c和server.c,分别用于消息的发送与接收。server建立一个 key为75的消息队列,等待其它进程发来的消息。当遇到类型为1的消息,则作为结束信号,取消该队列,并退出server。server每接收到一个消息后显示一句“(server)received”。client使用 key为75的消息队列,先后发送类型从10到1的消息,然后退出。最后一个消息,即是 server端需要的结束信号。client 每发送一条消息后显示一句“(client)sent”。二个程序分别编辑、编译为client与server,并按以下方式执行:./server &ipcs q./clientclient 和server 分别发送和接收了10条消息。2、观察运行结果,注意发送方发送消息和接收方接收消息的顺序。3、 使用消息队列,实现具有下列功能两个程序(进程):(1)程序A负责接受用户来自键盘的输入;(2)程序B负责实时输出用户由程序A接收的字符。程序A和程序B可分别在两个进程上同时运行。实验三 进程调度与死锁银行家算法一、 实验目的及要求1、 了解和掌握进程调度的算法和调度过程的控制。2、 通过模拟银行家算法,体会对设备安全分配的策略。二、实验设备(环境)及要求 一台运行windows或linux操作系统并安装C编译器的计算机。三、实验内容与步骤 1、设计一个程序模拟单处理机系统中的进程调度算法采用最高优先数优先的调度算法。程序包括:(1) 每个进程由一个进程控制块(PCB)表示。进程控制块可以包含如下信息:进程名、优先数、到达时间、需要运行时间、已用CPU时间、进程状态等。(2) 进程的优先数及需要的运行时间可以事先人为地指定(也可以由随机数产生)。进程的到达时间为进程输入的时间。(3) 进程的运行时间以时间片为单位进行计算。(4) 每个进程的状态可以是就绪W(Wait)、运行R(Run)或完成F(Finish)3中状态之一。(5) 就绪进程获得CPU后都只能运行一个时间片,用已占用CPU时间加1来表示。(6) 如果运行一个时间片后,进程的已占用CPU时间已达到所需要的运行时间,则撤销该进程,如果运行一个时间片后进程的已占用CPU时间还未达到所需要的运行时间,也即进程还需要继续运行,此时应将进程的优先数减1(即降低一级),然后把它插入就绪队列等待CPU。(7) 每进行一次调度程序都打印一次运行进程、就绪队列以及各个进程的PCB,以便进行检查。(8) 重复以上过程,直到所有进程都完成为止。2、设计银行家算法,模拟资源安全分配。实验四 存储器管理一、 实验目的及要求1、 帮助了解虚拟存储技术的特点。2、 验证掌握虚拟存储请求页式存储管理中几种基本页面置换算法的基本思想和实现过程。3、 比较各个页面置换算法的效率。二、实验设备(环境)及要求 一台运行windows或linux操作系统并安装C编译器的计算机。三、实验内容与步骤 设计一个程序,有一个虚拟存储区和内存工作区,并使用下述算法计算访问命中率(命中率=1-页面失效次数/页地址流长度)。(1) 最佳淘汰算法(OPT)。(2) 先进先出的算法(FIFO)。(3) 最近最久未使用算法(LRU)。该系统页地址流长度为320,页面失效次数为每次访问相应指令时,该指令对应的页不在内存的次数。 程序首先用srand()和rand()函数分别进行初始化、随机数定义和产生指令序列,然后将指令序列变换成相应的页地址流,并针对不同的算法计算出相应的命中率。1、 通过随机数产生一个指令序列。共320条指令,指令的地址按下述原则生成:(1)50%的指令是顺序执行的。(2)25%的指令是均匀分布在前地址部分。(3)25%的指令是均匀分布在后地址部分。具体的实施方法如下:(1) 在【0,319

温馨提示

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

评论

0/150

提交评论