操作系统实验报告----进程管理

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

实验内容:进程管理一、实验目的1、掌握Linux中进程的创建方法及执行情况;2、加深对进程、进程树等概念的理解;3、掌握Linux中如何加载子进程自己的程序;4、掌握父进程通过创建子进程完成某项任务的方法;5.、掌握系统调用exit()和_exit()调用的使用。6、分析进程竞争资源的现象,学习解决进程互斥的方法;进一步认识并发执行的实质二、实验内容(一)进程的创建1、编写一段程序,使用系统调用fork()创建两个子进程。当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符。#includestdio.hmain(){intp,x;p=fork();if(p0){x=fork();if(x0)printf(father\n);elseprintf(child2);}elseprintf(child1);}输出结果:child1child2father2、运行以下程序,分析程序执行过程中产生的进程情况。#includestdio.hmain(){intp,x;p=fork();if(p0)fork();else{fork();fork();}sleep(15);}实验步骤:编译连接gcc–oforktreeforktree.c后台运行./forktree&使用pstree–h查看进程树运行结果:├─gnome-terminal─┬─bash─┬─forktree─┬─forktree─┬─forktree───forktree││││└─forktree│││└─forktree││└─pstree分析:程序运行,系统首先创建一个进程forktree,执行到p=fork()创建一个子进程forktree,子进程获得处理机优先执行,父进程等待;执行else,当执行到第一个fork()函数时,子进程创建了一个进程forktree,称之为孙进程,孙进程获得处理机往下执行,子进程等待;执行到第二个fork()函数时,孙进程又创建一个进程forktree,称之为重孙进程,重孙进程很快执行完,将处理机还给孙进程,孙进程很快执行完,将处理机还给子进程;子进程继续往下执行,执行到第二个fork()函数,又创建一个进程forktree,称之为第二孙进程,并获得处理机执行,此进程很快执行完,将处理机还给子进程,子进程也很快执行完,将处理机还给父进程,父进程P0执行if语句,运行fork()函数,又创建一个进程forktree,称之为第二子进程,此进程获得处理机执行很快运行完,将处理机还给父进程,父进程运行sleep(15)语句,休眠15秒,用pstree命令查询进程树。3、运行程序,分析运行结果。#includestdio.hmain(){intp,x,ppid,pid;x=0;p=fork();if(p0){printf(parentoutputx=%d\n,++x);ppid=getpid();printf(Thiidnumberofparentis:ppid=%d\n,ppid);}else{printf(childoutputx=%d\n,++x);pid=getpid();printf(Thiidnumberofchildis:pid=%d\n,pid);}}运行结果:Parentoutputx=1Thisidnumberofparentis:ppid=3110Childoutputx=1Thisisnumberofchildis:pid=3111分析:fork创建进程的时候子进程与父进程共享代码区,子进程复制父进程的数据区,所以,两个进程中的数据互不影响都是1。4、loop.c#includestdio.hmain(){while(1){};{实验步骤:编译gccloop.c–oloop后台运行./loop&(可多次使用该命令)多次使用ps命令查看进程状态结果:FSUIDPIDPPIDCPRINIADDRSZWCHANTTYTIMECMD0S1000264526430800-1444waitpts/000:00:00bash0R10003622264578800-403-pts/000:00:18loop0R10003627264539800-403-pts/000:00:02loop0R10003628264539800-403-pts/000:00:01loop0R1000363026450800-625-pts/000:00:00ps(二)进程控制1、设计一程序,父进程创建一子进程,子进程的功能是输出“helloworld!”,使用execl()加载子进程的程序。程序代码如下:execl.c程序:#includestdio.h#includestdlib.h#includeunistd.hmain(){intp;p=fork();if(p0)printf(fatherisrunning!\n);else{printf(childisrunning!\n);execl(./hello,hello,0);printf(childisrunning!\n);}}hello.c程序:#includestdio.hmain(){printf(helloworld!\n);}输出结果:childisrunning!helloworld!fatherisrunning!2、运行以下程序,分析程序执行结果。#includestdlib.h#includestdio.hmain(){intp;p=fork();if(p0)printf(thisisparent);else{printf(thisischildfirst\n”);printf(thisischildsecond”);_exit(0);}}执行结果:thisischildfirstthisisparent[chun@RedFlagLinuxjjz]$换为exit(0)的执行结果:thisischildfirstthisischildsecondthisisparent[chun@RedFlagLinuxjjz]$分析:_exit()只是返回进程状态SZOMB,不清除缓冲区内容;exit(0)表示进程正常终止;(三)、进程的互斥1、利用catto_be_locked.txt查看下面程序的输出结果。#includestdio.h#includeunistd.hmain(){intp1,p2,i;int*fp;fp=fopen(to_be_locked.txt,w+);if(fp==NULL){printf(Failtocreatefile);exit(-1);}while((p1=fork())==-1);/*创建子进程p1*/if(p1==0){lockf(*fp,1,0);/*加锁*/for(i=0;i10;i++)fprintf(fp,daughter%d\n,i);lockf(*fp,0,0);/*解锁*/}else{while((p2=fork())==-1);/*创建子进程p2*/if(p2==0){lockf(*fp,1,0);/*加锁*/for(i=0;i10;i++)fprintf(fp,son%d\n,i);lockf(*fp,0,0);/*解锁*/}else{wait(NULL);lockf(*fp,1,0);/*加锁*/for(i=0;i10;i++)fprintf(fp,parent%d\n,i);lockf(*fp,0,0);/*解锁*/}}fclose(fp);}执行结果:daughter0daughter1daughter2daughter3daughter4daughter5daughter6daughter7daughter8daughter9son0son1son2son3son4son5son6son7son8son9parent0parent1parent2parent3parent4parent5parent6parent7parent8parent9分析:程序开始定义了文件读写指针用于打开指定的文件,当文件不存在时则自动创建。然后有创建了一个进程p1,p1获得处理机执行,给文件读写指针加锁,这样,即使p1失去处理机,其他获得处理机的进程也无法访问文件指针指向的文件,当p1再次获得处理机后继续执行直至进程p1结束并解锁;p1结束后父进程获得处理机执行又创建了进程p2,p2获得处理机执行,也给文件指针加锁,同理直至p2运行完解锁;p2结束后父进程获得处理机,父进程也给文件指针加锁,直至父进程执行完毕解锁,程序结束。2、按以下步骤分析下面的程序:(1)查看程序执行的结果并估计程序执行所需要时间。(2)将程序中所有的lockf函数加上注释,再观察程序执行的结果和估算程序执行所需的时间。(3)分析这两次执行的结果与时间的区别。#includestdio.h#includeunistd.hmain(){intp1,p2,i;p1=fork();/*创建子进程p1*/if(p1==0){lockf(1,1,0);/*加锁,这里第一个参数为stdout(标准输出设备的描述符)*/for(i=0;i10;i++){printf(child1=%d\n,i);sleep(1);}lockf(1,0,0);/*解锁*/}else{p2=fork();/*创建子进程p2*/if(p2==0){lockf(1,1,0);/*加锁*/for(i=0;i10;i++){printf(child2=%d\n,i);sleep(1);}lockf(1,0,0);/*解锁*/}else{lockf(1,1,0);/*加锁*/for(i=0;i10;i++){printf(parent%d\n,i);sleep(1);}lockf(1,0,0);/*解锁*/}}}未加注释的执行结果:child1=0child1=1child1=2child1=3child1=4child1=5child1=6child1=7child1=8child1=9child2=0child2=1child2=2child2=3child2=4child2=5child2=6child2=7child2=8child2=9parent0parent1parent2parent3parent4parent5parent6parent7parent8parent9加上注释的执行结果:child1=0child2=0parent0child1=1child2=1parent1child1=2child2=2parent2child1=3child2=3parent3child1=4child2=4parent4child1=5child2=5parent5child1=6child2=6parent6child1=7child2=7parent7child1=8child2=8parent8child1=9child2=0parent9分析:未加注释时程序运行时间大约是30秒,注释后的程序运行时间大约只是10秒钟。在注释掉之前,由于给后面的循环输出语句块加了锁,所以该语句只能被当前进程访问,即使其他进程获得处理机也无法访问,只有当前进程获得处理机并接着中断的地方继续执行完毕将锁释放其他的进程才能访问。所以输出结果按照顺序依次输出。由于sleep(1)语句在输出语句块中,每输出一次的要休眠1秒钟,所以大约需要30秒钟。注释掉所有lockf()函数后,循环输出语句块没有被加锁,当当前进程失去处理机后,获得处理机的其它进程也可以继续输出。另外,当进程child1输出一句后进入1秒休眠,此间进程child2获得处理机并输出一句也进入1秒休眠,此时进程parent获得处理机输出一句后也进入1秒休眠,由于三进程是依次进入休眠,因此也会依次醒来,依次获得处理机,依次输出,再依次休眠,直至循环输出

1 / 9
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功