操作系统上实验报告3课件_第1页
操作系统上实验报告3课件_第2页
操作系统上实验报告3课件_第3页
操作系统上实验报告3课件_第4页
操作系统上实验报告3课件_第5页
已阅读5页,还剩10页未读 继续免费阅读

下载本文档

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

文档简介

1、操作系统实验三报告 实验题目:进程管理及进程通信实验环境:虚拟机Linux操作系统实验目的:1.利用Linux提供的系统调用设计程序,加深对进程概念的理解。2.体会系统进程调度的方法和效果。3.了解进程之间的通信方式以及各种通信方式的使用。 实验内容:例程1:利用fork()创建子进程#include<stdio.h> #include<stdlib.h>#include<unistd.h> main()int i;if (fork()i=wait(0);/*父进程执行的程序段*/* 等待子进程结束*/printf("It is parent pr

2、ocess.n");printf("The child process,ID number %d, is finished.n",i);elseprintf("It is child process.n");sleep(10);/*子进程执行的程序段*/exit(1);/*向父进程发出结束信号*/运行结果:思考:子进程是如何产生的? 又是如何结束的?子进程被创建后它的运行环境是怎样建立的?答:子进程是通过函数fork()创建的,通过exit()函数自我结束的,子进程被创建后核心将为其分配一个进程表项和进程标识符,检查同时运行的进程数目,并且拷贝

3、进程表项的数据,由子进程继承父进程的所有文件。例程2:循环调用fork()创建多个子进程#include<stdio.h> #include<stdlib.h>#include<unistd.h>main() int i,j;printf(“My pid is %d, my fathers pid is %dn”,getpid(),getppid();for(i=0; i<3; i+)if(fork()=0)printf(“%d pid=%d ppid=%dn”, i,getpid(),getppid();else j=wait(0);Printf(“

4、 %d:The chile %d is finished.n” ,getpid(),j);运行结果:思考:画出进程的家族树。子进程的运行环境是怎样建立的?反复运行此程序看会有什么情况?解释一下。答:21440021441214442144621443214422144521447子进程的运行环境是由将其创建的父进程而建立的,反复运行程序会发现每个进程标识号在不断改变,这是因为同一时间有许多进程在被创建。例程3:创建子进程并用execlp()系统调用执行程序的实验#include<stdio.h>#include<unistd.h>main()int child_pid1

5、,child_pid2,child_pid3;int pid,status;setbuf(stdout,NULL);child_pid1=fork(); /*创建子进程1*/if(child_pid1=0) execlp("echo","echo","child process 1",(char *)0); /*子进程1 启动其它程序*/perror("exec1 error.n ");exit(1);child_pid2=fork(); /*创建子进程2*/if(child_pid2=0) execlp(&quo

6、t;date","date",(char *)0); /*子进程2 启动其它程序*/perror("exec2 error.n ");exit(2);child_pid3=fork(); /*创建子进程3*/if(child_pid3=0) execlp("ls","ls",(char *)0); /*子进程3 启动其它程序*/perror("exec3 error.n ");exit(3);puts("Parent process is waiting for chile

7、process return!");while(pid=wait(&status)!=-1) /*等待子进程结束*/ if(child_pid1=pid) /*若子进程1 结束*/printf("child process 1 terminated with status %dn",(status>>8);elseif(child_pid2=pid) /*若子进程2 结束*/printf("child process 2 terminated with status %dn",(status>>8);else i

8、f(child_pid3=pid) /*若子进程3 结束*/printf("child process 3 terminated with status %dn" ,(status>>8);puts("All child processes terminated.");puts("Parent process terminated.");exit(0);运行结果:思考:子进程运行其他程序后,进程运行环境怎样变化的?反复运行此程序看会有什么情况?解释一下。答:子进程运行其他程序后,这个进程就完全被新程序代替。由于并没有产生新

9、进程所以进程标识号不改变,除此之外旧进程的其它信息,代码段,数据段,栈段等均被新程序的信息所代替。新程序从自己的main()函数开始运行。反复运行此程序发现结束的先后次序是不可预知的,每次运行结果都不一样。原因是当每个子进程运行其他程序时,他们的结束随着其他程序的结束而结束,所以结束的先后次序在改变。例程4:观察父、子进程对变量处理的影响#include<stdio.h>#include<sys/types.h>#include<unistd.h>int globa=4;int main()pid_t pid;int vari=5;printf("

10、before fork.n");if (pid=fork()<0)printf("fork error.n");exit(0);elseif(pid=0)/*子进程执行*/globa+;vari-;printf("Child %d changed the vari and globa.n",getpid();else/*父进程执行*/wait(0);printf("Parent %d did not changed the vari and globa.n",getpid();printf("pid=%d,

11、globa=%d, vari=%dn",getpid(),globa,vari);/*都执行*/exit(0);运行结果:思考:子进程被创建后,对父进程的运行环境有影响吗?解释一下。答:子进程被创建后,对父进程的运行环境无影响,因为当子进程在运行时,它有自己的代码段和数据段,这些都可以作修改,但是父进程的代码段和数据段是不会随着子进程数据段和代码段的改变而改变的。例程5:管道通信的实验#include<stdlib.h>#include<stdio.h>main()int i,r,j,k,l,p1,p2,fd2;char buf50,s50;pipe(fd);

12、while(p1=fork()=-1);if(p1=0)lockf(fd1,1,0);/*子进程1 执行*/*管道写入端加锁*/sprintf(buf,"Child process P1 is sending messages! n");printf("Child process P1! n");write(fd1,buf,50);lockf(fd1,0,0);/*信息写入管道*/*管道写入端解锁*/sleep(5);j=getpid();k=getppid();printf("P1 %d is weakup. My parent proces

13、s ID is %d.n",j,k);exit(0);else while(p2=fork()=-1);if(p2=0)lockf(fd1,1,0);/*创建子进程2*/*子进程2 执行*/*管道写入端加锁*/sprintf(buf,"Child process P2 is sending messages! n");printf("Child process P2! n");write(fd1,buf,50);lockf(fd1,0,0);/*信息写入管道*/*管道写入端解锁*/sleep(5);j=getpid();k=getppid();

14、printf("P2 %d is weakup. My parent process ID is %d.n",j,k);exit(0);else l=getpid();wait(0);if(r=read(fd0,s,50)=-1)printf("Can't read pipe. n");elseprintf("Parent %d: %s n",l,s);wait(0);if(r=read(fd0,s,50)=-1)printf("Can't read pipe. n");elseprintf(&qu

15、ot;Parent %d: %s n",l,s);exit(0);运行结果:思考:(1)什么是管道?进程如何利用它进行通信的?解释一下实现方法。 (2)修改睡眠时机、睡眠长度,看看会有什么变化。解释。 (3)加锁、解锁起什么作用?不用它行吗?答:(1)管道是指能够连接一个写进程和一个读进程、并允许他们以生产者消费者方式进行通信的一个共享文件,又称pipe文件。由写进程从管道的入端将数据写入管道,而读进程则从管道的出端读出数据来进行通信。 (2)修改睡眠时机和睡眠长度都会引起进程被唤醒的时间不一,因为睡眠时机决定进程在何时睡眠,睡眠长度决定进程何时被唤醒。 (3)加锁、解锁是为了解决临

16、界资源的共享问题。不用它将会引起无法有效的管理数据,即数据会被修改导致读错了数据。例程7:软中断信号实验#include<stdlib.h>#include<stdio.h>main()int i,j,k;int func();signal(18,func();if(i=fork()j=kill(i,18);/*创建子进程*/*父进程执行*/*向子进程发送信号*/printf("Parent: signal 18 has been sent to child %d,returned %d.n",i,j);k=wait();/*父进程被唤醒*/prin

17、tf("After wait %d,Parent %d: finished.n",k,getpid();else/*子进程执行*/sleep(10);printf("Child %d: A signal from my parent is recived.n",getpid(); /*子进程结束,向父进程发子进程结束信号*/func()/*处理程序*/ int m;m=getpid();printf("I am Process %d: It is signal 18 processing function.n",m);运行结果:思考:

18、讨论一下它与硬中断有什么区别?答:硬中断是由外部硬件产生的,而软中断是CPU根据软件的某条指令或者软件对标志寄存器的某个标志位的设置而产生的。研究:什么是进程?如何产生的? 答:进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位。一旦操作系统发现了要求创建新进程的事件后,便调用进程创建原语Creat()按下述步骤创建一个新进程:(1)申请空白PCB。为新进程申请获得惟一的数字标识符,并从PCB集合中索取一个空白PCB。(2)为新进程分配资源。为新进程的程序和数据以及用户栈分配必要的内存空间。显然此时操作系统必须知道新进程所需内存的大小。对于批处理作业,其大小可在用户提出创建进程要

19、求时提供。若是为应用进程创建子进程,也应是在该进程提出创建进程的请求中给出所需内存的大小。对于交互型作业,用户可以不给出内存要求而由系统分配一定的空间。如果新进程要共享某个已在内在的地址空间(即已装入内存的共享段),则必须建立相应的链接。(3)初始化进程控件块。PCB的初始化包括:1.初始化标识信息,将系统分配的标识符和父进程标识符填入新PCB中;2.初始化处理机状态信息,使程序计数器指向程序的入口地址,使栈指针指向栈顶;3.初始化处理机控制信息,将进程的状态设置为就绪状态或静止就绪状态,对于优先级,通常是将它设置为最低优先级,除非用户以显式方式提出高优先级要求。(4)将新进程插入就绪队列,如果进程就绪队列能够接纳新进程,便将新进程插入就绪

温馨提示

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

评论

0/150

提交评论