操作系统实验个人总结.docx_第1页
操作系统实验个人总结.docx_第2页
操作系统实验个人总结.docx_第3页
操作系统实验个人总结.docx_第4页
操作系统实验个人总结.docx_第5页
已阅读5页,还剩30页未读 继续免费阅读

下载本文档

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

文档简介

操作系统实验报告班级: 姓名: 学号: 实验一 进程控制与描述一、实验目的通过对windows 2000编程,进一步熟悉操作系统的基本概念,较好地理解windows 2000的结构。通过创建进程、观察正在运行的进程和终止进程的程序设计和调试操作,进一步熟悉操作系统的进程概念,理解windows 2000中进程的“一生”。二、实验环境硬件环境:计算机一台,局域网环境;软件环境:windows 2000 professional、visual c+ 6.0企业版。三、实验内容和步骤第一部分:程序1-1windows 2000 的gui 应用程序windows 2000 professional下的gui应用程序,使用visual c+编译器创建一个gui应用程序,代码中包括了winmain()方法,该方法gui类型的应用程序的标准入口点。 # include # pragma comment(lib, “user32.lib” ) int apientry winmain(hinstance/* hinstance */ , hinstance/* hprevinstance */, lpstr/* lpcmdline */, int/* ncmdshow */ ) : messagebox( null, “hello, windows 2000” , “greetings”, mb_ok) ; return(0) ; 在程序1-1的gui应用程序中,首先需要windows.h头文件,以便获得传送给winmain() 和messagebox() api函数的数据类型定义。接着的pragma指令指示编译器/连接器找到user32.lib库文件并将其与产生的exe文件连接起来。这样就可以运行简单的命令行命令cl msgbox.cpp来创建这一应用程序,如果没有pragma指令,则messagebox() api函数就成为未定义的了。这一指令是visual studio c+ 编译器特有的。接下来是winmain() 方法。其中有四个由实际的低级入口点传递来的参数。hinstance参数用来装入与代码相连的图标或位图一类的资源,无论何时,都可用getmodulehandle() api函数将这些资源提取出来。系统利用实例句柄来指明代码和初始的数据装在内存的何处。句柄的数值实际上是exe文件映像的基地址,通常为0x00400000。下一个参数hprevinstance是为向后兼容而设的,现在系统将其设为null。应用程序的命令行 (不包括程序的名称) 是lpcmdline参数。另外,系统利用ncmdshow参数告诉应用程序如何显示它的主窗口 (选项包括最小化、最大化和正常) 。最后,程序调用messagebox() api函数并退出。如果在进入消息循环之前就结束运行的话,最后必须返回0。先分析程序功能,再写出运行结果:操作系统将当前运行的应用程序看作是进程对象。利用系统提供的惟一的称为句柄 (handle) 的号码,就可与进程对象交互。这一号码只对当前进程有效。在系统中运行的任何进程都可调用getcurrentprocess() api函数,此函数可返回标识进程本身的句柄。然后就可在windows需要该进程的有关情况时,利用这一句柄来提供。程序1-2: 获得和使用进程的句柄 # include # include void main() handle hprocessthis = : getcurrentprocess() ; dword dwpriority = : getpriorityclass(hprocessthis) ; std : cout “current process priority: ” ; switch(dwpriority) case high_priority_class: std : cout “high” ; break; case normal_priority_class: std: cout “normal” ; break; case idle_priority_class: std : cout “idle” ; break; case realtime_priority_class: std : cout “realtime” ; break; default: std : cout “” ; break; std : cout std : endl; 程序1-2中列出的是一种获得进程句柄的方法。对于进程句柄可进行的惟一有用的操作是在api调用时,将其作为参数传送给系统,正如程序1-2中对getpriorityclass() api函数的调用那样。在这种情况下,系统向进程对象内“窥视”,以决定其优先级,然后将此优先级返回给应用程序。openprocess() 和createprocess() api函数也可以用于提取进程句柄。前者提取的是已经存在的进程的句柄,而后者创建一个新进程,并将其句柄提供出来。先分析程序功能,再写出运行结果:程序1-3显示如何找出系统中正在运行的所有进程,如何利用openprocess() api函数来获得每一个访问进程的进一步信息。程序1-3 利用句柄查出进程的详细信息/ proclist项目# include # include # include dword getkernelmodepercentage(const filetime & ftkernel, const filetime & ftuser) ulonglong qwkernel =( ( (ulonglong) ftkernel.dwhighdatetime) 32) + ftkernel.dwlowdatetime; ulonglong qwuser =( ( (ulonglong) ftuser.dwhighdatetime) 32) + ftuser.dwlowdatetime; ulonglong qwtotal = qwkernel + qwuser; dword dwpct = (dword) ( ( (ulonglong) 100*qwkernel) / qwtotal) ; return(dwpct) ; void main() handle hsnapshot = : createtoolhelp32snapshot( th32cs_snapprocess, 0) ; processentry32 pe; : zeromemory(&pe, sizeof(pe) ) ; pe.dwsize = sizeof(pe) ; bool bmore = : process32first(hsnapshot, &pe) ; while(bmore) handle hprocess = : openprocess( process_query_information, false, pe.th32processid) ; if (hprocess != null) filetime ftcreation, ftexit, ftkernelmode, ftusermode; : getprocesstimes( hprocess, &ftcreation, &ftexit, &ftkernelmode, &ftusermode) ; dword dwpctkernel = : getkernelmodepercentage( ftkernelmode, ftusermode ) ; std : cout “process id: ” pe.th32processid “, exe file: ” pe.szexefile “, % in kernel mode: ” dwpctkernel std : endl; : closehandle(hprocess) ; bmore = : process32next(hsnapshot, &pe) ; 程序1-3程序首先利用windows 2000的新特性,即工具帮助库来获得当前运行的所有进程的快照。然后应用程序进入快照中的每一个进程,得到其以processentry32结构表示的属性。这一结构用来向openprocess() api函数提供进程的id。windows跟踪每一进程的有关时间,示例中是通过打开的进程句柄和getprocesstimes() api来直询得到有关时间的。接下来,一个定制的帮助函数取得了几个返回的数值,然后计算进程在内核模式下消耗的时间占总时间的百分比。程序的其余部分比较简单,只是将有关信息显示给用户,清除进程句柄,然后继续循环,直到所有进程都计算过为止。先分析程序功能,再写出运行结果:第二部分:进程的“一生”(共三个程序)1、 创建进程/创建子进程 # include # include # include void startclone(int ncloneid) tchar szfilenamemax_path ; : getmodulefilename(null, szfilename, max_path) ; tchar szcmdlinemax_path ; : sprintf(szcmdline, “”%s” %d”, szfilename, ncloneid) ; startupinfo si; : zeromemory(reinterpret_cast (&si) , sizeof(si) ) ; si.cb = sizeof(si) ; process_information pi; bool bcreateok = : createprocess( szfilename, 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) : sscanf(argv1 , “%d” , &nclone) ; std : cout “process id: “ : getcurrentprocessid() “, clone id: “ nclone std : endl; const int c_nclonemax = 25; if (nclone c_nclonemax) startclone(+nclone) ; : sleep(500) ; return 0; 本程序展示的是一个简单的使用createprocess() api函数的例子。首先形成简单的命令行,提供当前的exe文件的指定文件名和代表生成克隆进程的号码。大多数参数都可取缺省值,但是创建标志参数使用了:_ create_new_console _ 标志,指示新进程分配它自己的控制台,这使得运行示例程序时,在任务栏上产生许多活动标记。然后该克隆进程的创建方法关闭传递过来的句柄并返回main() 函数。在关闭程序之前,每一进程的执行主线程暂停一下,以便让用户看到其中的至少一个窗口。createprocess() 函数有_10_个核心参数?本实验程序中设置的各个参数的值是:a_szfilename_;b_szcmdline_;c. _null_;d_null_;e. _false_;f_create new console_;g_szcmdline_;h. _null_;i_&si_;j. _&pi_;程序运行时屏幕显示的信息是:*(此图是最后出现的一个图,在此之前连续出现几个图。)2、 正在运行的进程.使用进程和操作系统的版本信息 / version项目 # include # include void main() dword dwidthis = : getcurrentprocessid() ; dword dwverreq = : getprocessversion(dwidthis) ; word wmajorreq =( (word) dwverreq 16) ; word wminorreq = (word) dwverreq & 0xffff) ; std : cout “process 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) ; std : cout “task manager should now now indicate this” “process is high priority” std : endl; 分析程序,写出运行结果:当前pid信息:_1492_当前操作系统版本:_running on os:5.1_系统提示信息:task manager should now indiate this process is high priority._程序向读者表明了如何获得当前的pid和所需的进程版本信息。为了运行这一程序,系统处理了所有的版本不兼容问题。接着,程序演示了如何使用getversionex() api函数来提取osversioninfoex结构。这一数据块中包括了操作系统的版本信息。其中,“os : 5.0”表示当前运行的操作系统是:_windows2000_当前版本为_os:5.0_最后一段程序利用了操作系统的版本信息,以确认运行的是windows 2000。代码接着将当前进程的优先级提高到比正常级别高。单击ctrl + alt + del键,进入“windows任务管理器”,在“应用程序”选项卡中右键单击本任务,在快捷菜单中选择“转到进程”命令。在“windows任务管理器”的“进程”选项卡中,与本任务对应的进程映像名称是 (为什么?) :_ _vcspawn.exe_右键单击该进程名,在快捷菜单中选择“设置优先级”命令,可以调整该进程的优先级,如设置为“高”后重新运行程序,屏幕显示有变化吗?为什么?_屏幕显示有变化。process id值由1492变为:3152_3、 终止进程指令其子进程来“杀掉”自己的父进程 / procterm项目 # include # include # include static lpctstr g_szmutexname = “w2kdg.procterm.mutex.suicide” ; void startclone() tchar szfilename max_path ; : getmodulefilename(null, szfilename, max_path) ; tchar szcmdlinemax_path ; : sprintf(szcmdline, “” %s“ child” , szfilename) ; startupinfo si; : zeromemory(reinterpret_cast (&si) , sizeof(si) ) ;si.cb = sizeof(si) ; process_information pi; bool bcreateok = : createprocess( szfilename, 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() ; : 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; 程序说明了一个进程从“生”到“死”的整个一生。第一次执行时,它创建一个子进程,其行为如同“父亲”。在创建子进程之前,先创建一个互斥的内核对象,其行为对于子进程来说,如同一个“自杀弹”。当创建子进程时,就打开了互斥体并在其他线程中进行别的处理工作,同时等待着父进程使用releasemutex() api发出“死亡”信号。然后用sleep() api调用来模拟父进程处理其他工作,等完成时,指令子进程终止。当调用exitprocess() 时要小心,进程中的所有线程都被立刻通知停止。在设计应用程序时,必须让主线程在正常的c+ 运行期关闭 (这是由编译器提供的缺省行为) 之后来调用这一函数。当它转向受信状态时,通常可创建一个每个活动线程都可等待和停止的终止事件。在正常的终止操作中,进程的每个工作线程都要终止,由主线程调用exitprocess()。接着,管理层对进程增加的所有对象释放引用,并将用 getexitcodeprocess() 建立的退出代码从still_active改变为在exitprocess() 调用中返回的值。最后,主线程对象也如同进程对象一样转变为受信状态。等到所有打开的句柄都关闭之后,管理层的对象管理器才销毁进程对象本身。还没有一种函数可取得终止后的进程对象为其参数,从而使其“复活”。当进程对象引用一个终止了的对象时,有好几个api函数仍然是有用的。进程可使用退出代码将终止方式通知给调用getexitcodeprocess() 的其他进程。同时,getprocesstimes() api函数可向主调者显示进程的终止时间。先分析程序功能,再写出运行结果:1) _第一次执行时,它创建一个子进程,其行为如同“父亲”。表示:_ creating the child process.2) _用sleep() api调用来模拟父进程处理其他工作,等完成时,指令子进程终止。表示:telling the child process to quit在熟悉源代码的基础上,利用本实验介绍的api函数来尝试改进本程序 (例如使用getprocesstimes() api函数) 并运行。请描述你所做的工作:_getprocesstimes() api 可向主调者显示进程终止时间_四、实验总结进程具有的特征:结构特征、动态性、并发性、独立性和异步性。对于进程的定义可以从不同的角度来说,其中较为典型的定义有:(1)进程是程序的一次执行(2)进程是一个程序及其数据在处理机上顺序执行时发生的活动(3)进程是程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位。 对于传统os中的进程定义为:进程是进程实体的运行过程,使系统进行资源分配和调度的一个独立单位。 进程有三种基本状态:就绪状态、执行状态、阻塞状态。 创建一个进程:(1) 、申请空白的pcb(2) 为进城分配资源(3) 初始化进程控制块(4) 将进程插入就绪队列 终止一个进程: (1)根据被终止进程的标识符,从pcb集合中检索出该进程的pcb,从中读出该进程的状态 (2)若终止进程正处于执行状态,应立即中止该进程的执行,并置调度标志为真,用于指示该进程被终止进程的后应该重新进行调度 (3)若该进程还有子孙进程,还应该将其所有的子孙进程终止,以防止他们成为不可控的进程(4)将终止进程所拥有的全部资源,或者归还给其父进程,或者归还给系统(5)将终止进程pcb从所在队列中移除,等待其他程序来搜索信 通过实验更清楚的了解了进程,理解了进程的创建过程和终止过程实验二 并发与调度一、实验目的在本实验中,通过对事件和互斥体对象的了解,来加深对windows 2000线程同步的理解。通过分析实验程序,了解管理事件对象的api。了解在进程中如何使用事件对象,在进程中如何使用互斥体对象,线程如何通过文件映射对象发送数据。在linux redhat 9.0操作系统平台上,用pipe()创建一个管道文件,然后用fork()创建两个生产进程和两个消费进程,它们之间通过pipe()传递消息。二、实验环境硬件环境:计算机一台,局域网环境;软件环境:windows 2000 professional,linux redhat 9.0操作系统平台,visual c+ 6.0企业版。三、实验内容和步骤第一部分:互斥体对象本程序中显示的类ccountupdown使用了一个互斥体来保证对两个线程间单一数值的访问。每个线程都企图获得控制权来改变该数值,然后将该数值写入输出流中。创建者实际上创建的是互斥体对象,计数方法执行等待并释放,为的是共同使用互斥体所需的资源 (因而也就是共享资源) 。利用互斥体保护共享资源 / mutex项目 # include # include class ccountupdown public: ccountupdown(int naccesses) : m_hthreadinc(invalid_handle_value) , m_hthreaddec(invalid_handle_value) , m_hmutexvalue(invalid_handle_value) , m_nvalue(0) , m_naccess(naccesses) m_hmutexvalue = : createmutex( null, true, null) ; m_hthreadinc = : createthread( null, 0, incthreadproc, reinterpret_cast (this) , 0, null) ; m_hthreaddec = : createthread( null, 0, decthreadproc, reinterpret_cast (this) , 0, null) ; : releasemutex(m_hmutexvalue) ; virtual ccountupdown() : closehandle(m_hthreadinc) ; : closehandle(m_hthreaddec) ; : closehandle(m_hmutexvalue) ; virtual void waitforcompletion() if (m_hthreadinc != invalid_handle_value & m_hthreaddec != invalid_handle_value) : waitforsingleobject(m_hthreadinc, infinite) ; : waitforsingleobject(m_hthreaddec, infinite) ; protected: virtual void docount(int nstep) while (m_naccess 0) : waitforsingleobject(m_hmutexvalue, infinite) ; m_nvalue += nstep; std : cout “thread: ” : getcurrentthreadid() “value: ” m_nvalue “access: ” m_naccess std : endl; -m_naccess; : sleep(1000) ;/ 使显示速度放慢 : releasemutex(m_hmutexvalue) ; static dword winapi incthreadproc(lpvoid lpparam) ccountupdown* pthis = reinterpret_cast (lpparam) ; pthis - docount(+1) ; return(0) ; static dword winapi decthreadproc(lpvoid lpparam) ccountupdown* pthis = reinterpret_cast (lpparam) ; pthis - docount(-1) ; return(0) ; protected: handle m_hthreadinc; handle m_hthreaddec; handle m_hmutexvalue; int m_nvalue; int m_naccess; void main() ccountupdown ud(50) ; ud.waitforcompletion() ; 分析程序的运行结果,可以看到线程 (加和减线程) 的交替执行 (因为sleep() api允许windows切换线程) 。在每次运行之后,数值应该返回初始值 (0) ,因为在每次运行之后写入线程在等待队列中变成最后一个,内核保证它在其他线程工作时不会再运行。1) 请描述运行结果 (如果运行不成功,则可能的原因是什么?) 50进程交替使用互斥资源,从50开始直到0,如上图所示2) 根据运行输出结果,对照分析程序,可以看出程序运行的流程吗?请简单描述1、 创建互斥体用于访问数值;2、 解除程序释放对对象的引用简单的等待方法,在两个线程终止之前可暂停主调者;3、 使用等待方法,在两个线程终止之前可暂停主调者;4、 确保所有对象都已准备好;5、 等待两者完成(顺序并不重要);6、 循环,知道所有的访问都结束为止。第二部分 线程通过文件对象发送数据 windows 2000提供的线程间通讯类内核对象允许同一进程或跨进程的线程之间互相发送信息,包括文件、文件映射、邮件位和命名管道等,其中最常用的是文件和文件映射。这类对象允许一个线程很容易地向同一进程或其他进程中的另一线程发送信息。演示线程通过文件对象发送数据 # include # include static lpctstr g_szfilename = “w2kdg.fileobj.file.data.txt” ; static dword winapi threadproc (lpvoid lpparam) long nadd = reinterpret_cast (lpparam) ; tchar szfullname max_path ; : gettemppath(max_pa

温馨提示

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

评论

0/150

提交评论