-操作系统实验报告实验题目:进程控制专业计算机科学与技术学生姓名班级学号12006715指导教师指导单位计算机学院日期2014年11月13日-教师评语教师签名:年月日成绩评定备注-一、实验目的1.学习和了解进程控制的基本和常用的系统调用forkwaitsleepexitexec等等2.查看/usr/src/include/sched.h中的task_struct数据结构,并分析Linux操作系统进程状态。3.通过进程创建的应用实例,深刻理解进程创建的过程将以下例题输入运行,并分析运行结果程序例题1#includestdio.h#includesys/types.h#includeunistd.hintmain(void){pid_tpid;intdata=5;if((pid=fork())0){printf(forkerror\n);exit(0);}elseif(pid==0){data--;printf(child\'sdatais:%d\n,data);exit(0);}else{printf(parent\'sdatais:%d\n,data);}exit(0);}程序例题2用fork创建一个子进程,由其调用execve启动shell命令ps查看系统当前的进程信息#includestdio.h#includesys/types.h#includeunistd.hmain(){pid_tpid;char*path=/bin/ps;char*argv[5]={ps,-a,-x,NULL};printf(“Runpswithexecvebychildprocess:\n”);if((pid=fork())0)-{printf(“forkerror!”);exit(0);}elseif(pid==0){if(execve(path,argv,0)0){printf(“forkerror!”);exit(0);}printf(“childisok!\n”);exit(0);}wait();printf(“itisok!\n”);exit(0);}3.创建一个共享内存,实现一个生产者进程写共享内存,一个消费者进程读共享内存,并在写前读后输出写和读的内容。4.创建一个共享文件,实现一个写者进程写文件,2个读者在写者写后分别读出文件的内容,并给出读后评价。二、实验指导Linux中与进程控制相关的几个主要系统调用名/格式/参数功能返回值的解释fork()、vfork()创建一个字进程对父进程:返回子进程号对子进程:返回0错误:返回-1#includeunistd.hexecve(char*file,char**argv,char**envp)用指定程序覆盖当前程序代码正确:0错误:-1#includesys/types.h#includesys/wait.hpid_twait(int*statloc)等待进程终止正确:子进程的ID错误:-1getpid()、getppid()获得进程号-#includestdio.hvoidexit(intstatus)进程正常结束三、实验步骤(附程序原码)实验一:创建文件wang.c,编写C语言程序,实现在程序运行时通过系统调用fork()创建两个子进程,使父,子三进程并发进行,父亲进程执行时屏幕显示“parent”,儿子进程执行时屏幕显示“son”,女儿进程执行时屏幕显示“daugher”。程序如下:(进程一)#includestdio.hintmain(){intp1,p2,i;while((p1=fork())==-1);if(p1==0)for(i=0;i4;i++)printf(daughter%d\n,i);else{while((p2=fork())==-1);if(p2==0)for(i=0;i4;i++)printf(son%d\n,i);elsefor(i=0;i4;i++)printf(parent%d\n,i);}}(进程二)#includestdio.hintmain(){intpid;pid=fork();switch(pid){case-1:printf(forkfail\n);exit(1);case0:printf(subprocess\n);exit(0);default:wait(0);printf(completed\n);exit(0);}}实验二:编写程序,用fork创建两个子进程,再用系统调用signal让父进程捕捉键盘上传来的中-断信号,捕捉到中断信号后,父进程用系统调用kill向两个子进程发出信号,子进程终止。父进程等待两个子进程终止后终止。程序代码如下#includestdio.h#includesignal.h#includeunistd.hvoidwaiting(),stop();intwait_mark;intmain(){intp1,p2,stdout;signal(SIGINT,stop);while((p1=fork())==-1);if(p10){while((p2=fork())==-1);if(p20){wait_mark=1;sleep(5);waiting();kill(p1,16);kill(p2,17);wait(0);wait(0);printf(Parentprocessiskilled!\n);exit(0);}else{wait_mark=1;signal(17,stop);waiting();lockf(stdout,1,0);printf(Childprocess2iskilledbyparent!\n);lockf(stdout,0,0);exit(0);}}else{wait_mark=1;signal(16,stop);waiting();lockf(stdout,1,0);printf(Childprocess1iskilledbyparent!\n);-lockf(stdout,0,0);exit(0);}}voidwaiting(){while(wait_mark!=0);}voidstop(){wait_mark=0;}四、运行结果及其结果分析实验一:结果分析:0:在子进程中,pid变量保存的fork()返回值为0,表示当前进程是子进程。0:在父进程中,pid变量保存的fork()返回值为子进程的pid值。-1:创建失败。实验二:结果分析:从键盘输入中断信号,父进程收到中断信号用系统调用kill向两个子进程发出信号,子进程收到信号后分别输出Childprocess1iskilledbyparent!,Childprocess2iskilledbyparent!结束进程并exit(0),父进程收到两个exit(0)后输出Parentprocessiskilled!结束进程。-五、思考题1、当首次调用新创建进程时,其入口在哪里?解:调用fork函数的下一条语句开始。2、可执行文件加载时进行了哪些处理?解:可执行文件加载时首先是创建一个新进程的fork系统调用,然后用于实现进程自我终止的exit系统调用;改变进程原有代码的exec系统调用;用于将调用进程挂起并等待子进程终止的wait系统调用;获得进程标识符的getpid系统调用等处理过程。3、什么是进程同步?wait()是如何实现进程同步的?解:异步环境下的一组并发进程因直接制约而互相发送消息而进行互相合作、互相等待,使得各进程按一定的速度执行的过程称为进程间的同步。解:首先程序在调用fork()机那里了一个子进程后,马上调用wait(),使父进程在子进程调用之前一直处于睡眠状态,这样就使子进程先运行,子进程运行exec()装入命令后,然后调用wait(0),使子进程和父进程并发执行,实现进程同步。