操作系统实验 第三讲 进程的创建

更新时间:2023-10-06 13:04:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

操作系统 实 验 报 告

课程名称 实验项目名称 学号 操作系统实验 进程的创建 班级 20120616 计算机科学姓名 计算机科学 学生所在学院 与技术学院 实验室名称地点

专业 与技术 指导教师 初妍 21#428 哈尔滨工程大学 计算机科学与技术学院

一、实验概述

1. 实验名称

2. 实验目的

进程的创建

(1)练习使用 EOS API 函数 CreateProcess 创建一个进程,掌

握创建进程的方法,理解进程和程序的区别。

(2)调试跟踪 CreateProcess 函数的执行过程,了解进程的创 建过程,理解进程是资源分配的单位。

3. 实验类型

4. 实验内容

3.1 准备实验

3.2 练习使用控制台命令创建 EOS 应用程序的进程

3.3 练习通过编程的方式让应用程序创建另一个应用程序的进程 3.4 调试 CreateProcess 函数 3.5 调试 PsCreateProcess 函数

3.6 练习通过编程的方式创建应用程序的多个进程

验证型实验

二、实验环境

操作系统 windos xp 编译器 OS Lab 语言 c语言

三、实验过程 1. 设计思路

创建10个进程时,可以使用 PROCESS_INFORMATION 类型定义一个有 10 个元素的数组,每一个元素对应一个进程。使用一个循环创建 10 个子进程,然后再使用一个循环等待 10 个子进程结束,得到退出码后关闭句柄。

2. 算法实现

在创建10个进程的程序中,为了保证只有在10个进程都创建成功的情况下才执行后续操作,引入一个变量locked,只有10个程序都创建成功时locked=1,

1

出现创建失败的情况时locked=0,当locked=1时再执行后续操作。 3. 需要解决的问题及解答

问题1: 程序创建2个进程创建的情况下,实验指导P133-4的*NewProcess和6的*ProcessObject变化情况,监控变量界面截图。(答案见3.5)

问题2:尝试根据之前对PsCreateProcess函数和PspCreateProcessEnvironment函数执行过程的跟踪调试,绘制一幅进程创建过程的流程图。

问题3:思考与练习,在源代码文件NewTwoProc.c提供的源代码基础上进行修改,要求使用hello.exe同时创建10个进程。要给出源代码及解释和运行界面截图。(代码见“源程序并附上注释”部分)

2

4. 源程序并附上注释

使用 hello.exe 同时创建 10 个进程,代码如下: #include\int main(int argc,char*argv[]) {

STARTUPINFO StartupInfo;

PROCESS_INFORMATION jincheng[10];

ULONG ulExitCode; //子进程退出码 INT nResult=0;

//main函数返回值。0表示成功,非0表示失败。

#ifdef_DEBUG

__asm(\

#endif

printf(\//使子进程和父进程使用相同的标准句柄。

StartupInfo.StdInput=GetStdHandle(STD_INPUT_HANDLE); StartupInfo.StdOutput=GetStdHandle(STD_OUTPUT_HANDLE); StartupInfo.StdError=GetStdHandle(STD_ERROR_HANDLE);

3

int i,j,k,l,m,n; int locked=1;

for(j=0;j<10;j++){//同时创建10个进程

if(CreateProcess(\//创建成功什么都不执行

else//创建失败,输出失败信息 {

printf(\nResult=1; locked=0;

//locked为o,则说明10个进程中有失败的,后续操作不再进行

}

}

if(locked==1){ //创建子进程成功,等待子进程运行结束。

for(k=0;k<10;k++) { }

//得到并输出子进程的退出码。 for(l=0;l<10;l++){

}

GetExitCodeProcess(jincheng[l].ProcessHandle,&ulExitCode); printf(\WaitForSingleObject(jincheng[k].ProcessHandle,INFINITE);

//关闭不再使用的句柄。 for(m=0;m<10;m++) { }

CloseHandle(jincheng[m].ProcessHandle); CloseHandle(jincheng[m].ThreadHandle);

}//end if }

4

return nResult;

5. 程序运行时的初值和运行结果

3.1 准备实验

建立一个EOS Kernel 项目和 EOS 应用程序项目。 3.2 练习使用控制台命令创建 EOS 应用程序的进程

将本实验文件夹中的Hello.exe文件拖动到FloppyImageEditor工具窗口的文件列表中释放,Hello.exe文件即被添加到软盘镜像文件中,按F5启动调试,在EOS的控制台中输入命令“A:\\Hello.exe”后回车,结果如下图:

3.3 练习通过编程的方式让应用程序创建另一个应用程序的进程

使用 NewProc.c 文件中的源代码替换之前创建的 EOS 应用程序项目中的 EOSApp.c 文件内的源代码,F5 启动调试,激活虚拟机窗口查看应用程序输出的内容:

5

3.4 调试 CreateProcess 函数

F5 启动调试 EOS 应用程序,在 main 函数中调用 CreateProcess 函数的代码行(第 57 行)添加一个断点。按 F5 继续调试,在断点处中断。 按 F11 调试进入 CreateProcess 函数。在“调试”菜单的“窗口”中选择“反汇编”,会在“反汇编”窗口中显示 CreateProcess 函数的指令对应的反汇编代码。“反汇编”窗口的左侧显示的是指令所在的虚拟地址。可以看到所有指令的虚拟地址都大于 0x80000000,说明内核( kernel.dll) 处于高 2G 的虚拟地址空间中,如图:

设置 main 函数的调用堆栈帧为活动的。在“反汇编”窗口中查看 main 函数的指令所在的虚拟地址都是小于 0x80000000,说明应用程序( eosapp.exe)处于低 2G 的虚拟地址空间中,如图:

6

3.5 调试 PsCreateProcess 函数

在 PsCreateProcess 函数中找到调用 PspCreateProcessEnvironment 函数的代码行( create.c文件的第 163 行), 并在此行添加一个断点。 按 F5 继续调试,到此断点处中断。按 F11 调试进入 PspCreateProcessEnvironment 函数。

在调用 ObCreateObject 函数的代码行( create.c 文件的第 418 行)添加一个断点。按 F5 继续调试,到此断点处中断。按 F10 执行此函数后中断。将表达式*NewProcess 添加到“监视”窗口中,继续一步步调试可以观察到进程控制块的成员变量的值的变化,如下图:

接下来调试初始化进程控制块中各个成员变量的过程:

当从 PspCreateProcessEnvironment 函数返回到 PsCreateProcess 函数后,停止按 F10。此时“监视”窗口中已经不能再显示表达式*NewProcess 的值了,在PsCreateProcess 函数中是使用ProcessObject 指针指向进程控制块的,所以将表达式*ProcessObject 添加到“监视”窗口中就可以继续观察新建进程控制块中的信息。接下来继续使用 F10 一步步调试 PsCreateProcess 函数中的代码,同样要注意进程控制块中的成员变量的变化:

7

3.6 练习通过编程的方式创建应用程序的多个进程

用 NewTwoProc.c 文件中的源代码替换 EOS 应用程序项目中 EOSApp.c 文件内的源代码,生成后启动调试,查看多个进程并发执行的结果。

8

四、实验体会

实验过程中,在调试时添加监视对象时,因为少了*导致结果不正确,后请教同学后解决了,另外在动手实现10个进程创建的问题时,一开始没有头绪,后来和原创建2个进程的程序对比以及for循环提示,写出了程序,并和同学讨论后,修正了对进程创建失败时的操作。

9

本文来源:https://www.bwwdw.com/article/j7gd.html

Top