《操作系统》实验讲义--OS实验指导书.doc_第1页
《操作系统》实验讲义--OS实验指导书.doc_第2页
《操作系统》实验讲义--OS实验指导书.doc_第3页
《操作系统》实验讲义--OS实验指导书.doc_第4页
《操作系统》实验讲义--OS实验指导书.doc_第5页
已阅读5页,还剩93页未读 继续免费阅读

下载本文档

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

文档简介

操作系统实验讲义计算机科学与工程学院2015年3月实验一 Linux初步实验预备知识一、 创建实验平台如果实验室里的计算机安装了Windows操作系统,则可以先安装VMWare软件(一般使用工作站版本)并启动它,来创建一个虚拟机,然后在其中安装Linux操作系统。这样就可以从虚拟机中启动Linux系统,并完成相应的实验。VMWare软件和Linux操作系统的安装十分简单,这里就不做介绍。二、 Linux下的proc文件系统在Linux操作系统中,提供了一套非常有用的在用户态检查内核状态和系统特征的机制,这就是proc文件系统。该文件系统安装在 /proc 目录中。比起Windows的任务管理器来,proc文件系统的功能更强大:它能提供更多的系统信息,能修改部分系统信息,还能通过编程来扩充其中的内容。该文件系统将进程的地址空间、系统的硬件信息(包括CPU、内存状态以及网卡等各种硬件设备)、系统相关机制(中断、I/O)等内容全部设置成虚拟的Linux文件。它以一种特殊的文件系统的方式,为访问系统内核数据的操作提供接口。也就是说,这个文件系统中所有的文件都是特殊文件,这些特殊文件一般与外部设备无关,所涉及到的介质通常室内存和CPU。当从一个特殊文件“读”出时,所读出的数据都是由系统内部按一定的规则临时生成的,或从内存中收集、加工出来的,反之亦然。换言之,这些文件的内容都不存在任何存储设备上,而是在读/写的时候才根据系统中的有关信息生成出来,或映射到系统中的有关变量或数据结构中。/proc 目录中的每个文件都有一组分配给它的非常特殊的文件许可权,并且每个文件属于特定的用户标识,这里面的文件仅仅包含以下几种权限(除非root用户特别授权):l 只读任何用户都不能更改该文件,它用于表示系统信息。l root写/proc 目录中的一些文件是可写的,但通常只能由root用户来写。l root读有些文件对一般系统用户是不可见的,而对root用户是可见的。l 其他:三种许可权的组合在Linux的/proc的目录中,除了/proc/sys目录下的文件外,其余大部分的属性都属于root,并且对全部用户是只读的。/proc/sys目录下则存放的是内核参数,并设计成为运行时可修改的。下表列出/proc目录下的一些重要文件。目录/文件名描述apm高级电源管理cmdline内核命令行cpuinfoCPU信息devices可用设备信息filesystems系统支持的文件系统interrupts中断信息ioports端口使用信息kcore内核映象kmsg内核消息meminfo内存信息modules内核加载模块列表mounts已加载文件信息partions系统识别的分区表stat全面信息统计状态表swap交换分区使用情况version内核版本uptime系统正常运行时间sys内核参数在/proc目录下你会发现一些以数字命名的子目录,它们是进程目录。系统中当前运行的每一个进程都有一个对应的目录在/proc目录下,以进程ID号为目录,他们就是读取进程信息的接口,每个进程中包含的文件如下表所示:子目录名包含内容cmdline该进程的命令行参数enviroment进程环境变量的值Fd进程打开的文件的描述符Mem进程的内存使用情况stat进程状态cwd进程的当前目录root进程的根目录maps内存映象statm进程内存状态信息exe当前进程的可执行文件(链接)在/proc目录下,有一个特殊的子目录sys,该目录下的文件记录了内核各方面的运行参数。用户可更改这些文件的值,结果是直接修改内核中的相应参数。在修改之前,最好确切地了解这些内核的参数的作用,以及安全的取值范围。下面举几个例子:1、/proc/sys/kernel/acct该文件有3个可配置值,根据包含日志的文件系统上可用空间数量(百分比表示),这些值控制何时开始进行进程记帐:第一个值:如果可用空间低于这个百分比值,则停止记帐;第二个值:如果可用空间高于这个百分比值,则开始记帐;第三个值:检查上面2个值的频率(以秒为单位)。要更改这个文件的某个值,应该回送用空格隔开,默认设置为2 4 30,表示如果包含日志的文件系统上只有少于2的可用空间,则这些值会使记帐停止;如果有高于4的可用空间,则再次启动记帐;每30秒做一次检查。2、/proc/sys/fs/file-max该文件指定了可以分配的文件句柄的最大数目。如果用户得到错误信息,说明由于打开文件数已经达到了最大值,而不能打开更多的文件,则可能需要增加该值。可将这个值设置为任意多个文件,并且能通过将一个新数字值写入该文件来更改该值。3、/proc/sys/kernel/domainname该文件允许配置网络域名。它没有默认值;可能已经设置了域名,也可能没有。4、/proc/sys/kernel/hostname该文件允许配置网络主机名。同样,它也没有默认值;可能已经设置了主机名,也可能没有。5、/proc/sys/kernel/printk该文件有四个数字值,它们根据日志记录消息的重要性,定义将其发送到何处。关于不同日志级别的更多信息。该文件的四个值依次为:控制台日志级别:优先级高于该值的消息将被打印至控制台。默认的消息日志级别:将用该优先级来打印没有优先级的消息。最低的控制台日志级别:控制台日志级别可被设置的最小值(最高优先级)。默认的控制台日志级别:控制台日志级别的默认值。默认设置为6 4 1 7。6、/proc/sys/kernel/shmall该文件是在任何给定时刻系统上可以使用的共享内存的总量(以字节为单位)。默认设置为2097152。7、/proc/sys/kernel/shmax该文件指定内核所允许的最大共享内存段的大小(以B(字节)为单位)。默认设置为33554432。8、/proc/sys/kerneI/shmmni该文件表示用于整个系统共享内存段的最大数目。如上所述,/proc/sys目录不仅提供了内核信息,而且可以通过它修改内核参数。但是必须很小心,因为不当的修改可能会造成系统崩溃。最好是先找一台无关紧要的计算机,测试成功后,再应用到读者自己的系统上。要改变内核的参数,只要用vi编辑或echo参数重定向到文件即可。实验部分一、 实验目的与要求通过proc文件系统观察整个Linux内核和系统的一些重要特征,并编写一个程序,使用proc文件系统获得以及修改系统的各种配置参数。本实验需要学生具有Linux的基本操作技能,以及采用C语言编写程序的能力。二、 实验内容以超级用户的身份登录Linux系统,并进入/proc目录,键入“ls”命令,查看该目录下的内容,同时查看每个文件的读写权限。1、 请回答下列问题: CPU的类型和型号。 所使用的Linux的版本。 从启动到当前时刻所经过的时间。 当前内存状态。2、编写一个程序getinfo.c,编译后并在命令行带命令参数来运行该程序,获得内核参数 (例如网络主机名、共享内存容量、文件句柄的最大参数等) 在屏幕上显示出来。运行过程实例如下(获取文件句柄最大参数):rootLinux / # ./getinfo filemaxfilemax :186263、编写一个程序setsys.c,编译后并在命令行带命令参数来运行该程序,用来修改内核参数(任意的参数均可(例如网络主机名、共享内存容量、文件句柄的最大参数等)。运行过程实例如下:rootLinux / # ./setsys filemaxInput filemax parameter:21545注释:实例中加波浪线的部分为键盘输入内容。通过运行getinfo filemax来确认是否修改成功。三、 解决方案本实验完全不涉及任何的内核编程,而完全使用标准c库中的函数。事实上,只需要编写一个简单的读文本文件的程序,就可以直接用于读proc文件系统中的文件。下面给出一个简单的程序框架,读者可以在这个基础上添加自己的代码,从而完成上述的实验。# include# include# include# includeint main(int argc,char* argv ) int fd=open(argv1,FLAG,MODE);/ 文件名作为参数传入。FLAG和/ MODE的值由打开的功能决定if (fd!=-1) / 读/写相应的内核参数 close(fd);else /做错误处理return EXIT_SUCCESS;附录A: vi编辑器vi编辑器是所有Unix及Linux系统下标准的编辑器,它的强大不逊色于任何最新的文本编辑器,这里只是简单地介绍一下它的用法和一小部分指令。由于对Unix及Linux系统的任何版本,vi编辑器是完全相同的,因此您可以在其他任何介绍vi的地方进一步了解它。Vi也是Linux中最基本的文本编辑器,学会它后,您将在Linux的世界里畅行无阻。1、 vi的基本概念 基本上vi可以分为三种状态,分别是命令模式(command mode)、插入模式(Insert mode)和底行模式(last line mode),各模式的功能区分如下: 1) 命令行模式command mode) 控制屏幕光标的移动,字符、字或行的删除,移动复制某区段及进入Insert mode下,或者到 last line mode。 2) 插入模式(Insert mode) 只有在Insert mode下,才可以做文字输入,按ESC键可回到命令行模式。 3) 底行模式(last line mode) 将文件保存或退出vi,也可以设置编辑环境,如寻找字符串、列出行号等。 不过一般我们在使用时把vi简化成两个模式,就是将底行模式(last line mode)也算入命令行模式command mode)。 2、vi的基本操作 a) 进入vi 在系统提示符号输入vi及文件名称后,就进入vi全屏幕编辑画面:$ vi myfile 不过有一点要特别注意,就是您进入vi之后,是处于命令行模式(command mode),您要切换到插入模式(Insert mode)才能够输入文字。初次使用vi的人都会想先用上下左右键移动光标,结果电脑一直哔哔叫,把自己气个半死,所以进入vi后,先不要乱动,转换到插入模式(Insert mode)再说吧! b) 切换至插入模式(Insert mode)编辑文件 在命令行模式(command mode)下按一下字母i就可以进入插入模式(Insert mode),这时候你就可以开始输入文字了。 c) Insert 的切换 您目前处于插入模式(Insert mode),您就只能一直输入文字,如果您发现输错了字!想用光标键往回移动,将该字删除,就要先按一下ESC键转到命令行模式(command mode)再删除文字。d) 退出vi及保存文件 在命令行模式(command mode)下,按一下:冒号键进入Last line mode,例如: : w filename (输入 w filename将文章以指定的文件名filename保存) : wq (输入wq,存盘并退出vi) : q! (输入q!, 不存盘强制退出vi) 3、命令行模式(command mode)功能键 1). 插入模式 按i切换进入插入模式insert mode,按i进入插入模式后是从光标当前位置开始输入文件; 按a进入插入模式后,是从目前光标所在位置的下一个位置开始输入文字; 按o进入插入模式后,是插入新的一行,从行首开始输入文字。 2). 从插入模式切换为命令行模式 按ESC键。 3). 移动光标 vi可以直接用键盘上的光标来上下左右移动,但正规的vi是用小写英文字母h、j、k、l,分别控制光标左、下、上、右移一格。 按ctrl+b:屏幕往后移动一页。 按ctrl+f:屏幕往前移动一页。 按ctrl+u:屏幕往后移动半页。 按ctrl+d:屏幕往前移动半页。 按数字0:移到文章的开头。 按G:移动到文章的最后。 按$:移动到光标所在行的行尾。 按:移动到光标所在行的行首 按w:光标跳到下个字的开头 按e:光标跳到下个字的字尾 按b:光标回到上个字的开头 按#l:光标移到该行的第#个位置,如:5l,56l。 4). 删除文字 x:每按一次,删除光标所在位置的后面一个字符。 #x:例如,6x表示删除光标所在位置的后面6个字符。 X:大写的X,每按一次,删除光标所在位置的前面一个字符。 #X:例如,20X表示删除光标所在位置的前面20个字符。 dd:删除光标所在行。 #dd:从光标所在行开始删除#行 5). 复制 yw:将光标所在之处到字尾的字符复制到缓冲区中。 #yw:复制#个字到缓冲区 yy:复制光标所在行到缓冲区。 #yy:例如,6yy表示拷贝从光标所在的该行往下数6行文字。 p:将缓冲区内的字符贴到光标所在位置。注意:所有与y有关的复制命令都必须与p配合才能完成复制与粘贴功能。 6). 替换 r:替换光标所在处的字符。 R:替换光标所到之处的字符,直到按下ESC键为止。 7). 回复上一次操作 u:如果您误执行一个命令,可以马上按下u,回到上一个操作。按多次u可以执行多次回复。 8). 更改 cw:更改光标所在处的字到字尾处 c#w:例如,c3w表示更改3个字 9). 跳至指定的行 ctrl+g列出光标所在行的行号。 #G:例如,15G,表示移动光标至文章的第15行行首。 4、Last line mode下命令简介 在使用last line mode之前,请记住先按ESC键确定您已经处于command mode下后,再按:冒号即可进入last line mode。 A) 列出行号 set nu:输入set nu后,会在文件中的每一行前面列出行号。 B) 跳到文件中的某一行 #:#号表示一个数字,在冒号后输入一个数字,再按回车键就会跳到该行了,如输入数字15,再回车,就会跳到文章的第15行。 C) 查找字符 /关键字:先按/键,再输入您想寻找的字符,如果第一次找的关键字不是您想要的,可以一直按n会往后寻找到您要的关键字为止。 ?关键字:先按?键,再输入您想寻找的字符,如果第一次找的关键字不是您想要的,可以一直按n会往前寻找到您要的关键字为止。 D) 保存文件 w:在冒号输入字母w就可以将文件保存起来。 E 离开vi q:按q就是退出,如果无法离开vi,可以在q后跟一个!强制离开vi。 qw:一般建议离开时,搭配w一起使用,这样在退出的时候还可以保存文件。 5、vi命令列表1)下面列出命令模式下的一些键的功能: h 左移光标一个字符 l 右移光标一个字符 k 光标上移一行 j 光标下移一行 光标移动至行首0 数字0,光标移至文章的开头G 光标移至文章的最后$ 光标移动至行尾 Ctrl+f 向前翻屏Ctrl+b 向后翻屏 Ctrl+d 向前翻半屏Ctrl+u 向后翻半屏 i 在光标位置前插入字符 a 在光标所在位置的后一个字符开始增加o 插入新的一行,从行首开始输入ESC 从输入状态退至命令状态x 删除光标后面的字符 #x 删除光标后的个字符X (大写X),删除光标前面的字符 #X 删除光标前面的#个字符dd 删除光标所在的行#dd 删除从光标所在行数的#行yw 复制光标所在位置的一个字#yw 复制光标所在位置的#个字yy 复制光标所在位置的一行#yy 复制从光标所在行数的#行p 粘贴 u 取消操作cw 更改光标所在位置的一个字#cw 更改光标所在位置的#个字 2) 下表列出行命令模式下的一些指令 w filename 储存正在编辑的文件为filename wq filename 储存正在编辑的文件为filename,并退出vi q! 放弃所有修改,退出viset nu 显示行号 /或? 查找,在/后输入要查找的内容 n 与/或?一起使用,如果查找的内容不是想要找的关键字,按n或向后(与/联用)或向前(与?联用)继续查找,直到找到为止。 附录B: Linux系统源程序文件的编译示例实验二 进程的控制和通信(Windows2000)实验目的通过对Windows 2000编程,进一步熟悉操作系统的基本概念,并能较好地理解Windows 2000的结构。通过创建进程,观察进程的运行和终止程序以及调试操作,进一步熟悉操作系统的进程概念,理解Windows 2000进程的生命周期。实验预备知识三、 应用程序基础Windows 2000可以识别的应用程序包括控制台应用程序、GUI应用程序和服务应用程序。控制台应用程序可以创建GUI,GUI应用程序可以作为服务来运行,服务也可以向标准的输出流写入数据。不同类型应用程序间的惟一重要区别是其启动方法。Windows 2000是以Windows NT技术构建的,提供了创建控制台应用程序的能力,使用户可以利用标准的C+工具,如iostream库中的cout和cin对象,来创建小型应用程序。当系统运行时,Windows 2000的服务通常要向系统用户提供所需功能。服务应用程序由服务控制管理器(SCM)加以调用。SCM是操作系统的集成部分,负责响应系统启动以开始服务、指导用户控制或从另一个服务中来的请求。其本身负责使应用程序的行为像一个服务。当令C+编译器创建可执行程序时,编译器将源代码编译成OBJ文件,然后将其与标准库相链接。产生的EXE文件是装载器指令、机器指令和应用程序等数据的集合。装载器指令告诉系统从哪里装载机器代码。在进行某些设置后,进入开发者提供的main()或WinMain()函数的低级入口点。机器代码中包括有控制逻辑,所做的事包括跳转到Windows API函数,进行程序计算或向磁盘写入数据等。Windows允许开发人员将大型应用程序分为较小的、互相有关系的服务模块,即动态链接库(DLL)代码块,在其中包含应用程序所使用的机器代码和应用程序的数据。1GUI应用程序在使用传统的C语言 main()入口点的应用程序时,C+编译器知道,当用户在程序中包括这个方法时,就应该把编译结果的文件标志为EXE文件。在例1-1中,C+编译器创建一个GUI应用程序,代码中包括了WinMain()方法,这是GUI类型的应用程序的标准入口点。该函数的原型在winbase.h中声明。函数调用格式:int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPreInstance,LPSTR lpCmdLine, Int nShowCmd);参数:hInstance指定实例句柄,该句柄惟一地标识了这一应用程序,其他Windows函数可以通过将该句柄作为参数来调用该程序。hPreInstance该参数只是为了与早期的版本相兼容,在32位Windows程序中,该概念已经不再被采用,所以总是设置为NULL。lpCmdLine指定用于应用程序的命令行,可以通过它将文件在程序启动时载入内存。nShowCmd指定该应用程序在运行时以何种方式显示(正常、最大化和最小化中选一)。为了进一步理解应用程序的构造,下面给出一个简单的GUI应用程序。例2-1 GUI应用程序。#include/告诉连接器,与包括MessageBox()API函数的user32库进行连接#pragma comment(lib,user32.lib)/这是一个可以弹出信息框然后退出的简单的应用程序int APIENTRY WinMain(HINSTANCE,HINSTANCE,LPSTR,int) MessageBox( NULL, /没有父窗口 Hello,Windows 2000,/消息框中的文本信息 Greetings,/消息框标题 MB_OK); /消息框中有一个OK按钮 return 0;/返回0以便通知系统不进入消息循环在GUI应用程序中,首先需要Windows.h头文件,它向WinMain()和MessageBox()API函数提供所需的数据类型定义。 然后,pragma指令指示编译器/连接器找到user32.lib库文件并将其与产生的EXE文件连接起来。如果没有pragma指令,则MessageBox()API函数就成为未定义的了。这一指令是Visual Studio C+编译器特有的。接下来是WinMain()方法。其中有4个由实际的低级入口点传递来的参数。hInstance参数用来装入与代码相连的图标或位图一类的资源,无论何时,都可用GetModuleHandle()API函数将这些资源提取出来。系统利用实例句柄来指明代码和初始的数据装在内存的何处。句柄的实际数值是EXE文件映像的基地址,通常为0x00400000。下一个参数hPreInstance是为向下兼容而设的,现在系统将其设为NULL。应用程序的命令行(不包括程序的名称)是lpCmdLine参数。另外,系统利用nCmdShow参数告诉应用程序如何显示它的主窗口(选项包括最小化、最大化和正常)。最后,程序调用MessageBox()API函数,之后退出。如果在进入消息循环之前就结束运行的话,最后必须返回0。2进程对象操作系统将当前运行的应用程序看作是进程对象。利用系统提供的惟一的称为句柄(handle)的标识,就可与进程对象交互。这一标识只对当前进程有效,因此正在系统中运行的任何进程都可调用GetCurrentProcess()API函数,返回进程本身的句柄。相关API函数说明(1) GetModuleHandle函数功能:该函数用来获得一个应用程序或动态链接库的模块句柄。函数格式:HMODULE GetModulehandle(LPCTSTR lpModuleName);参数:lpModuleName指定的模块名,通常是与模块的文件名相同的一个名字。返回值:若函数调用成功,返回值为模块句柄;否则返回值为0。(2)GetCurrentProcess函数功能:该函数返回当前进程的句柄。函数格式:HANDLE GetCurrentProcess(void);参数:无。返回值:若函数调用成功,返回值为当前进程的句柄。(3)GetPriorityClass函数功能:该函数用来获得进程的基准优先级。函数格式:DWORD GetPriorityClass(HANDLE);参数:HANDLE指定进程句柄。返回值:若函数调用成功,返回值为指定进程的基准优先级;若函数调用失败,返回值为0。备注:如果要了解进程的返回代码,就需要有PROCESS_QUERY_INFORMATION的访问权限。(4)CreateToolhelp32Snapshot函数功能:该函数获得系统中当前进程的快照。函数格式:HANDLE CreateToolhelp32Snapshot(DWORD dwFlags,DWORD th32ProcessID);参数:dwFlags指定快照中包括系统线程的情况;th32ProcessID指定进程的标志符。返回值:若函数调用成功,则返回值为进程快照的句柄。备注:若参数dwFlags为TH32CS_SNAPPROCESS,则表明快照包括系统中的所有线程,且th32ProcessID为包含在快照中进程的进程标志符。(5)ZeroMemory函数功能:该函数用来分配存储空间,并将其清零。函数格式:VOID ZeroMemory(PVOID Destination,SIZE_T Length);参数:Destination指向分配空间的起始地址;Length分配空间字节长度。返回值:该函数没有返回值。(6)Process32First函数功能:该函数用来获得系统快照中的第一个进程信息。函数格式:BOOL Process32First(HANDLE hSnapshot,LPPROCESSENTRY32 lppe); 参数:hSnapshot指定快照句柄;Lppe指向PROCESSENTRY32结构指针。返回值:如果返回值为真,则将系统快照中的第一个进程信息复制到缓冲区,否则不做任何操作。(7)OpenProcess函数功能:该函数用来获得一个已经存在的进程对象的句柄。函数格式:HANDLE OpcnProcess(DWORD dwDesiredAccess,BOOL bInheritHandle,DWORD dwProcessId);参数:dwDesiredAccess指定进程对象的访问权限。此参数可以是下列值的一个或几个的组合:PROCESS_ALL_ACCESS指定对象无限制的访问。PROCESS_CREATE_PROCESS内部使用。PROCESS_CREATE_THREAD使用函数CreateRemoteThread中的句柄在进程中创建一个线程。PROCESS_DUP_HANDLE允许在函数DuplicateHandle中使用进程对象。PROCESS_QUERY_INFORMATION 允许GetExitCodeClass和GetPriority等函数获得关于进程的信息。PROCESS_SET_QUOTA 允许使用AssignProcessToJobObject和 SetProcessWorkingSetSize等函数中的句柄来设置内存限制。PROCESS_SET_INFORMATION 允许使用函数SetPriorityClass来设置有关进程的信息。PROCESS_TERMINATE 允许使用函数TerminateProcess中的进程句柄来终止进程。PROCESS_VM_OPERATION 允许使用函数VirtualProtectEx和WriteProcessMemory中的进程句柄来改变进程的虚拟内存。PROCESS_VM_READ允许使用函数ReadProcessMemory中的进程句柄从虚拟内存中读出数据。PROCESS_VM_WRITE 允许使用函数WriteProcessMemory中的进程句柄向虚拟内存中写人数据。SYNCHRONIZE允许使用任何等待函数中的进程句柄来等待进程的终止。bInheritHandle若要子进程获得对该对象的访问权限,应设置为TRUE,否则设为FALSE。dwProcessId指定系统范围内的进程标志符。返回值:若函数调用成功,则返回进程对象的句柄;否则返回FALSE。(8)GetProcessTimes函数功能:该函数用来获得与进程有关的时间信息。函数格式:BOOL GetProcessTimes(HANDLE hProcess,LPFILETIME lpCreationTime,LPFILETIME lpExitTime,LPFILETIME lpKernelTime,LPFILETIME lpUserTime);参数:hProcess一个进程句柄。lpcreationTime 指定一个FILETIME结构,在其中含有进程的创建时间。lpExitTime 指定一个FILETIME结构,在其中含有进程的中止时间。lpKernelTime 指定一个FILETIME结构,在其中含有进程在核心态运行时所消耗的时间。lpUserTime指定一个FILETIME结构,在其中含有进程在用户态运行时所消耗的时间。返回值:如果函数调用成功,返回非零值;如果函数调用失败,返回值为0。(9)CloseHandle函数功能:该函数关闭一个打开的对象句柄。其作用为释放动态申请的内存空间,这样可以保证系统资源不会泄漏,程序可以在安全的状态下运行。函数格式:BOOL CloseHandle(HANDLE hObject);参数:hObject打开对象的句柄。返回值:如果函数调用成功,返回非零值;否则返回值为0。备注:该函数可以关闭下列对象的句柄:通信设备、控制台输入、控制台屏幕缓冲区、事件、文件、文件映射、作业、邮件槽、临界区、命名管道、进程、信息量、套接字、线程、令牌。CloseHandle函数使指定的对象句柄无效,减少对象的句柄数,并进行对象的保留检查,当一个对象的最后一个句柄被关闭后,该对象就从系统中被删除掉。关闭一个线程的句柄并终止相关的线程,要删除一个线程对象,必须先终止该线程,并关闭该线程的所有句柄。(10)Process32Next函数功能:该函数用来获得系统快照中下一个进程的信息。函数格式:BOOL Process32Next(HANDLE hSnapshot,LPPROCESSENTRY32 lppe);参数:hSnapshot指定快照句柄;lppe指定一个PROCESSENTRY32结构。返回值:如果进程列表的下一人口点被复制到缓冲区,返回TRUE。为了理解进程句柄的应用,下面给出一个简单的获得句柄的方法。例2-2获得和使用进程句柄,确定自身优先权的一个简单应用程序。#include#includeint main()HANDLE hProcessThis=GetCurrentProcess();/从当前进程中提取句柄/请求内核提供该进程所属的优先权类DWORD dwPriority=GetPriorityClass(hProcessThis);/发出消息,为用户描述该类printf(current process priority:);switch(dwPriority) case HIGH_PRIORITY_CLASS: printf(Highn); break; case NORMAL_PRIORITY_CLASS: printf(Normaln); break; case IDLE_PRIORITY_CLASS: printf(Idlen); break; /case REAL_TIME_ PRIORITY_CLASS: /printf(Realtimen); /break; default: printf(n); break;为了进一步掌握进程句柄的应用,下面给出一个利用句柄获得进程详细信息的方法。例2-3利用进程句柄获得进程详细信息, 应用程序显示当前运行进程名字以及在核心态下占用时间的百分比。#include#include#include#pragma comment(lib,kernel32.lib)/当在用户态及核心态下都提供所耗时间时,计算在核心态下所消耗的时间(64位表示)DWORD GetKernelModePercentage(const FILETIME &ftKernel,const FILETIME &ftUser) /将FILETIME结构转化为64位整数 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);/ int main() /获得系统中当前进程的快照HANDLE hSnapshot=CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, /获得当前进程 0); /如果是当前进程,就将其忽略/初始化过程入口PROCESSENTRY32 pe;/描述进程入口的PROCESSENTRY32结构ZeroMemory(&pe,sizeof(pe);/为 pe分配存储空间,并将其清0pe.dwSize=sizeof(pe);/执行循环BOOL bMore=Process32First(hSnapshot,&pe); /获得系统快照中的第一个进程信息while(bMore) /打开用于读取的进程HANDLE hProcess=OpenProcess( PROCESS_QUERY_INFORMATION,/指明要得到信息 FALSE,/不必继承这一句柄 pe.th32ProcessID);/要打开的进程if(hProcess!=NULL)/找出进程的时间FILETIME ftCreation,ftKernelMode,ftUserMode,ftExit;GetProcessTimes( hProcess, /所感兴趣的进程&ftCreation, /进程的启动时间 &ftExit, /结束时间(如果有的话)&ftKernelMode, /在核心状态下消耗的时问 &ftUserMode); /在用户状态下消耗的时间 /计算核心状态下消耗的时间百分比DWORD dwPctKernel=GetKernelModePercentage(ftKernelMode,/在核心状态下消耗的时间ftUserMode);/在用户状态下消耗的时间 /显示进程的某些信息coutprocess ID:pe.th32ProcessID,EXE file:pe.szExeFile ,%in Kernel mode:dwPctKernelendl;CloseHandle(hProcess);/关闭句柄bMore=Process32Next(hSnapshot,&pe);/转向下一个进程四、 进程控制Windows所创建的每个进程都从调用CreateProcess()API函数开始,该函数的任务是在对象管理器子系统内初始化进程对象。每一进程都以调用ExitProcess()或TerminateProcess()API函数终止。通常应用程序的框架负责调用ExitProcess()函数。对于C+运行库来说,这一调用发生在应用程序的main()函数返回之后(如果采用C运行库,则调用WinMain()函数)。1进程创建基本的win32进程管理函数是CreateProcess,可以创建拥有单个线程的进程。因为进程需要代码,所以有必要指定可执行程序文件名作为CreateProcess调用的一部分。CreateProcess有10个参数支持其灵活性和强大功能。该函数并不返回一个handle,而是在一个结构(在调用中指定)中返回两个表示进程和线程的句柄。相关API函数说明如下:(1)CreateProcess函数功能:该函数用来创建进程。函数格式:BOOL CreateProcess( LPCTSTR lpApplicationName, LPTSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCTSTR lpCurrentDirectory, LPSTARTUPINF0 lpStartupInfo, LPPROCESS_INFORMATI0N lpProcessInformation);参数:lpApplicationName和lpCommandLine指定新进程使用的可执行文件和传递给新进程的命令行字符串。lpszCommandLine 可以设定CreateProcess中用于创建新进程的命令行。 CreateProcess在解析lpCommandLine字符串的时候,先查看字符串中的第一个符号,如果是一个可执行文件名且不含有扩展名,就假定它的扩展名为EXE。CreateProcess将按照以下顺序来搜索可执行文件:含有调用进程的EXE文件的目录;调用进程的当前目录;Windows系统目录,该目录由GetSystemDirectory函数得到;Windows目录,该目录由GetWindowsDirectory函数得到;列在PATH环境变量中的目录。如果文件名中包含了完整的路径,系统就使用完整路径搜索可执行文件。如果系统找到了可执行文件,就创建一个新进程,并生成一个4GB的地址空间,从而使可执行文件的代码和数据映射到这个地址空间。lpProeessAllributes和lpThreadAllributes 是指向进程和线程安全属性结构的 指针。当用NULL表示时,则为默认的安全性。bInheritHandles表明新进程是否继承调用进程的打开句柄的副本。继承的句柄与原来的句柄具有相同属性。dwCreationFlags是几个标志的组合,其中包含以下几个标志: CREATE_SUSPENDED指定新进程的主线程创建时处于挂起状态,直到调用ResumeThread函数时才能运行。 DETACHED_PROCESS和CREATE_NEW_CONSOLE 相互排斥;二者不能同时使用。第一个标志是创建没有控制台的进程,第二个标志是创建新的有控制台的进程。如果二者都没有设置,进程将继承父进程的控制台。 CREATE_NEW_PROCESS_GROUP 指定新进程是新进程组的根进程。如果组中所有的进程都共享同一控制台,则它们都将接收控制台的控制信号。lpVEnvironment指向新进程的环境块。如果此值为NULL,进程会使用父进程的环境块。环境块包含名称和值字符串,如搜索路径。lpCurrentDirectory指向新进程的驱动器和目录。若为NULL,将使用父进程的工作 目录。lpStartupInfo指向新进程的主窗口外观和标准设备句柄。使用GetStartupInfo 函数得到父进程信息。 lpProcessInformation指向包含返回的进程、线程句柄和进程、线程标识符的PROCESS_INFORMATION结构。返回值:如果进程和主线程创建成功,则返回TRUE。(2)GetCurrentProcessId函数功能:该函数用来获得当前进程的标识符。函数格式:DWORD GetCurrentProcessId (void):参数:无。返回值:返回当前

温馨提示

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

评论

0/150

提交评论