操作系统-实验三-进程管理-实验报告(共21页).docx
精选优质文档-倾情为你奉上计算机与信息工程学院实验报告姓名 学号专业软件工程年级2017级课程操作系统主讲教师党兰学实验时间(年月日时)2019年10月23日实验地点计算机学院201机房辅导教师党兰学实验题目进程管理实验目的1. 加深对进程概念的理解,明确进程和程序的区别;2. 进一步认识并发执行的实质;3. 了解父进程和子进程之间的关系;4. 查看进程管理命令。实验环境(硬件和软件)硬件:PC机 软件:Oracle VM Virtualbox Linux一、实验内容1.练习在shell环境下编译执行程序(注意: 在vi编辑器中编写名为的c语言源程序 用linux自带的编译器gcc编译程序,例如:gcc o test 编译后生成名为的可执行文件; 最后执行分析结果;命令为:./test)注意:linux自带的编译程序gcc的语法是:gcc o 目标程序名 源程序名,例如:gcc o sample1 ,然后利用命令:./sample 来执行。如果仅用“gcc 源程序名”,将会把任何名字的源程序都编译成名为的目标程序,这样新编译的程序会覆盖原来的程序,所以最好给每个源程序都起个新目标程序名。2.进程的创建仿照例子自己编写一段程序,使用系统调用fork()创建两个子进程。当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示“a”,子进程分别显示字符“b”和“c”。观察记录屏幕上的显示结果,并分析原因。3.分析程序实验内容要在给出的例子程序基础上,根据要求进行修改,对执行结果进行分析。二、实验步骤1. 利用fork()创建一个小程序(1) 编写程序#include <sys/>main () int i=5; pid_t pid; pid=fork(); for(;i>0;i-) if (pid < 0) printf("error in fork!"); else if (pid = 0) printf("i am the child process, my process id is %d and i=%dn",getpid(),i); else printf("i am the parent process, my process id is %d and i=%dn",getpid(),i); for(i=5;i>0;i-) if (pid < 0) printf("error in fork!"); else if (pid = 0) printf("the child process, my process id is %d and i=%dn",getpid(),i); else printf("the parent process, my process id is %d and i=%dn",getpid(),i); (2) 运行程序(3)分析程序在这里,主程序先运行,在屏幕上输出一个a,之后两个子程序分别运行而输出c和b。2 子进程对存取空间的复制(1) 编写程序(2)运行程序(3) 分析程序通过scanf(“%d”,&i);语句读取一个整数存在i,之后创建两个子程序,输入10后,子程序运行,之后经过一些读取赋值操作,输出i的值。3 父子进程执行进程分析(1) 编写程序(2) 运行程序(3) 程序分析三次结果不同是因为printf(“In which processn”);所处位置经过变换,处于父子程序之后,父子程序之前和父程序之中。4 修改程序验证父子进程关系(1) 编写程序文本代码:#include <sys/>#include <>#include <>#include <>#include <>#include <sys/>#include <sys/>#include <sys/>#include <>#define MY_SHMKEY To end, input 0 when prompted.nn");printf("Input a number:n");scanf("%d", &local); while( local ) =0; =-1; =SEM_UNDO; semop(semid, &semopbuf, 1);/* P(S1) */ *shmptr = local; =1; =1; =SEM_UNDO; semop(semid, &semopbuf, 1);/* V(S2) */ printf("Input a number:n"); scanf("%d", &local); else/* acts as server */ semid=semget(MY_SEMKEY, 2, IPC_CREAT|0666); shmptr=(int *)shmat(shmid, 0, 0);semval=1;semctl(semid, 0, SETVAL, semval);/* set S1=1 */semval=0;semctl(semid, 1, SETVAL, semval);/* set S2=0 */ signal(SIGINT, sigend); signal(SIGTERM, sigend); printf("ACT CONSUMER! To end, try Ctrl+C or use kill.nn"); while(1) =1; =-1; =SEM_UNDO; semop(semid, &semopbuf, 1);/* P(S2) */ printf("Shared memory set to %dn", *shmptr); =0; =1; =SEM_UNDO; semop(semid, &semopbuf, 1);/* V(S1) */ void sigend(int sig) shmctl(shmid, IPC_RMID, 0); semctl(semid, IPC_RMID, 0); exit(0);(2) 运行程序(3) 分析程序本示例主要体现进程间的直接制约关系,由于使用共享存储区,也存在间接制约关系。进程分为服务进程和客户进程,服务进程只有一个,作为消费者,在每次客户进程改变共享存储区内容时显示其数值。各客户进程作为生产者,如果共享存储区内容已经显示(被消费),可以接收用户从键盘输入的整数,放在共享存储区。编译后执行,第一个进程实例将作为服务进程,提示:ACT CONSUMER! To end, try Ctrl+C or use kill.服务进程一直循环执行,直到用户按Ctrl+C终止执行,或使用kill命令杀死服务进程。其他进程实例作为客户进程,提示:Act as producer. To end, input 0 when prompted.客户进程一直循环执行,直到用户输入0。5 模拟临界资源访问的示例程序(1) 编写程序文本代码:#include <sys/>#include <>#include <>#include <>#include <>#include <sys/>#include <sys/>#include <>#define MY_SHMKEY n");shmptr->top=MAX_BLOCK-1;for(i=0; i<MAX_BLOCK; i+) shmptr->stacki=MAX_BLOCK-i; sleep();/* cause sleep forever. */ void sigend(int sig) shmctl(shmid, IPC_RMID, 0); semctl(semid, IPC_RMID, 0); exit(0);void relblock(void) if<0) printf("No block to release!");return; shmptr->top+; shmptr->stackshmptr->top=;int getblock(void) if(shmptr->top<0) printf("No free block to get!");return; +=shmptr->stackshmptr->top; shmptr->top-;void showhelp(void) printf("navailable COMMAND:nn"); printf("helptlist this helpn"); printf("listtlist all gotten block numbern"); printf("gettget a new blockn"); printf("reltrelease the last gotten blockn"); printf("endtexit this programn");void showlist(void) int i; printf("List all gotten block number:n"); for(i=0; i<=; i+)printf("%dt", i);void getcmdline(void) printf("n> "); fgets(cmdbuf, MAX_CMD-1, stdin);(2) 运行程序(3) 程序分析本示例的临界资源是一个建立在共享存储区的栈,由服务进程建立并初始化。初始状态下共享栈满,里面顺序放置一系列正整数(自栈顶向下:1,2,3.),代表空闲块号。客户进程利用共享栈进行数据块的分配和释放,以得到、归还一个块号代表,并不进行任何后续操作。程序中getblock过程从共享栈中弹出一个块号(分配),relblock过程把一个已分配块号压入共享栈(释放)。为简单起见,已分配块号在本地也使用栈结构保存,因而每次释放的是最后分配的块号。编译后执行,第一个进程实例将作为服务进程,提示:NO OTHER OPERATION but press Ctrl+C or use kill to end.服务进程完成初始化后将进入睡眠状态,直到用户按Ctrl+C终止执行,或使用kill命令杀死服务进程。其他进程实例作为客户进程,进入后首先有命令帮助提示,然后显示命令提示符“> ”,在命令提示下可以使用的命令包括:help显示可用命令list列出所有已分配块号get分配一个新块rel释放最后分配块号end退出程序三、实验数据记录1. 2. 3.4.5.四、问题讨论(1)在程序运行过程中出现一个错误,错误语句:exit(0);原因:少了一个头文件:#include <>(2)心得体会:通过本次实验我了解了fork()函数等关于进程应用的函数并且学会了父子进程的各种基本操作,同时我也了解到做实验要谨慎加小心,一点差错就会导致全局崩溃。专心-专注-专业