第三次实验进程的创建.doc_第1页
第三次实验进程的创建.doc_第2页
第三次实验进程的创建.doc_第3页
第三次实验进程的创建.doc_第4页
第三次实验进程的创建.doc_第5页
已阅读5页,还剩8页未读 继续免费阅读

下载本文档

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

文档简介

甘肃政法学院本科生实验报告(三)姓名:杨万学院:计算机科学专业:计算机科学与技术 班级:2009级计本实验课程名称:操作系统实验实验日期:2012年 5 月 20 日指导教师及职称:何珍祥实验成绩:开课时间:2011-2012学年 第二学期甘肃政法学院实验管理中心印制实验题目进程的创建小组合作否姓名杨万班级2009级计本学 号200981010142一、实验目的1.理解和掌握UNIX(和Linux)进程控制系统调用的功能。3.理解进程的调度和执行2.理解如何创建一个进程、改变进程执行程序、进程的终止和父子进程同步3.提高对进程控制系统调用的编程能力二实验环境1. 操作系统Windows XP2.装有虚拟机Linux的系统三、实验内容与步骤1 fork()函数用fork()函数创建进程时,语句调用系列如下:#include#includePit_t fork(void); fork()函数是一个单调用双返回的函数,也就是说,该函数有父进程调用,执行时,在父进程中返回子进程标识,在子进程中返回0。fork()调用后,子进程是父进程的一个复制。都是从fork()调用语句开始执行。 编写一个程序,使用fork()函数创建一个子进程,程序运行时,父进程输出两个变量的值,子进程将父进程的两个变量值改变后输出,并分析程序运行结果产生的原因。代码如下所示:#include#include#includeint glob=3;int main(void) pid_t pid;int loc=3; printf(before fork();glod=%d,loc=%d.n,glob,loc); if(pid=fork()0) printf(fork() error. n); exit(0); else if(pid=0) glob+; loc-; printf(child process changes glob and loc: n); else wait(0); printf(parent process doesnt change the glob and loc:n); printf(glob=%d,loc=%dn,glob,loc); exit(0);2 vfork()函数 用vfork()函数创建进程时,语句调用序列如下;#include#includePit_t fork(void); 用vfork()函数创建进程是,通常使用exec()函数紧跟其后,以便为新创建的进程指派另一个可执行程序, 用vfork()函数系统调用,观察运行结果,分析结果产生的原因,比较fork和vfork的区别。代码如下:#include#include#includeint glob=3;int main(void) pid_t pid; int loc=3; if(pid=vfork()0) printf(vfork() errorn); exit(0); else if(pid=0) glob+; loc-; printf(child process changes the glob and locn); exit(0); else printf (parent process doesnt change the glob and locn); printf(glob=%d,val=%dn,glob,loc);3 给进程指定一个新的运行程序的函数exec(). 一个进程的调用exec()函数来运行一新程序。之后该进程的代码段.数据段和堆栈段被新程序所代替。新程序从自己的main()函数开始进行。 编写一个程序,运行时一个进程调用exec()函数来运行一个新的程序。建立print1.c文件,编译生成可执行文件print1是主程序file4.c中exec函数指派的可执行程序名,将传递给程序的参数和环境变量进行输出。其代码如下:printe1.c代码:#includeint main(int argc,char * argv)int n;char * * ptr;extern char * * environ;for(n=0;nargc;n+)printf(argv%d:%sn,n,argvn);for(ptr=environ; * ptr!=0;ptr+)printf(%sn,* ptr);exit(0);file4.c代码如下:#include#include#include#includechar * env_list=USER=root,PATH=/root/,NULL;int main()pid_t pid;if(pid=fork()0)printf(fork error!n);exit(0);else if(pid=0)if(execle(/root/print1,print1,arg1,arg2,(char *)0,env_list)0)printf(execle error!n);exit(0);if(waitpid(pid,NULL,0)0)printf(WAIT ERROR!n);exit(0);if(pid=fork()0)printf(fork error!n);exit(0);else if(pid=0)if(execlp(print1,print1,arg1,(char *)0)0)printf(execle error!n);exit(0);exit(0);4. 进程终止函数exit()。 在Linux系统中,进程通过执行系统调用exit()来终止自己。 exit()调用的两个例子,观察结果,进一步理解exit()函数,代码如下:#includemain() printf(this is a exit system call! n); exit(0); printf(this sentence never be displayen:n); #includemain() printf(this is a _exit_test system call! n); printf(content in buffer); exit(0);5 wait()函数和sleep()函数。 编写一个父子进程同步的实例,并分析结果,改变其sleep()的参数,观察结果,理解体会wait()和sleep()函数各自的功能。代码如下:#includemain() int pid1; if(pid1=fork() if(fork() printf(parents context,n); printf(parents waiting the child1 terminate,n); wait(0); printf(parents waiting the child2 terminate,n); wait(0); printf(parent terminates,n); exit(0); else printf(child2s context,n); sleep(5); printf(child2 terminates,n); exit(0); else if(pid1=0) printf(child1s context,n); sleep(10); printf(child1 terminates,n); exit(0); 6 编写一段程序,父进程使用fork()创建两个子进程,利用输出函数putchar父进程显示字符”a”,两个子进程分别显示“b”和“c”。多次运行该程序,观察并记录屏幕上的显示结果,分析原因。代码如下: #include#include#includeint main() int pid;if(pid=fork() if(fork() printf(parent process is n); putchar(A); printf(n); else printf(child2 process is n); putchar(C); printf(n); else if(pid=0) printf(child1 process is n); putchar(B); printf(n); 四、实验过程与分析一,fork()函数调用运行结果如下图:分析:该程序可能产生二种结果,第一种:rootlocalhost root# ./file1before fork():glob = 3, loc = 3.child process changes glob and loc:glob = 4,loc = 2parent process doesnt change the glob and loc:glob = 3,loc = 3第二种:rootlocalhost root# ./file1before fork():glob = 3, loc = 3.parent process doesnt change the glob and loc:glob = 3,loc = 3child process changes glob and loc:glob = 4,loc = 2 当程序运行到if(pid=fork()0)时,表示创建进程失败,输出“fork()error”,程序故障中止。创建成功后,程序运行时产生两个进程,有main函数产生一个父进程以及程序执行时调用fork产生一个子进程。当执行到fork后形成两个并发进程,第一种情况,父进程先执行,子进程后执行,而第二种恰好相反。2. vfork()函数调用运行结果如下图: 运行结果只有一种,由于vfork()函数与fork()函数的区别是:fork()函数执行时不对父子进程次序进行任何限制。而vfork()函数调用后,子进程先运行,父进程挂起,直到子进程exit(0)调用,子进程结束,父进程才激活执行。所以运行结果只有一种。3. 函数exec()的程序运行结果如下图: 先运行子进程print1.c ,生成子进程可执行文件,在运行源程序,当运行到execle()时,调用子进程的可执行文件的路径,传递的参数有可执行程序的路径名、程序所需参数及程序执行的环境变量。故执行结果为arg0:print1(即程序),arg1:arg1,arg2:arg2(即参数)和USER=root,PATH=/root/(即环境变量)。4. exit()函数系统调用运行结果如下图: 系统调用exit()来终止自己,所以在第一个程序中:当程序执行到exit(0)时,程序将结束,不再执行下一句,所以输出只有一条语句。5. wait()和sleep()系统调用。 运行结果如下图:分析:该程序是父进程首先创建一个子进程,若成功,再创建另一个子进程,之后三个进程并发执行,它们运行是随机的,上图是其中的一种情况,由运行结果可知程序的运行顺序,子进程创建成功后,首先开始子进程1执行,当执行到sleep(10)时,子进程1被阻塞,接着执行子进程2,当执行到sleep(5)时,同样也被阻塞,此时跳到父进程中执行,执行到第一个wait(0)时被阻塞,此时由于子进程2的睡眠时间比子进程1的时间短,系统此时唤醒了子进程2,当子进程2执行exit(0)后结束子进程2,父进程再次被唤醒,继续执行父进程,当执行到第二个wait(0)时再次被阻塞,此时跳到子进程1执行,直到运行到exit(0)后退出子进程1,父进程再次继续执行直到结束。 若将子进程1,2的sleep()都改为sleep(0)时的执行结果如下图所示分析:此时子进程1和2将不会被sleep()阻止,先将子进程1运行完后,在运行子进程2,最后运行父进程,直到结束。 在将子进程1,2的sleep()都改为sleep(5)时的执行结果如下图所示分析:该程序和第一个程序基本一样,先运行子进程1和子进程2,在跳回父进程,唯一不同的是在父进程中当运行到wait(0)时,因为子进程1和2 sleep睡眠时间一样,此时系统调用了子进程1,再次调用子进程2,所以运行结果如上图。六,运行结果如下图:如上图可知产生了一种结果:先输出进程1,在运行进程2,最后运行父进程,即BCA。由程序可知函数fork创建子进程后,形成了3个并发进程,每个进程执行都用可能。putchar输出语句时间很短,产生的结果不止上面一种,还有可能是ABC,CAB,CBA.等几种结果。注释掉所有printf的输出语句,在快速运行后产生结果如下:五、实验总结 本实验通过利用系统调用fork()和vfork()创建子进程,创建成功后,父进程

温馨提示

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

评论

0/150

提交评论