操作系统课程设计报告操作系统课程设计报告专业:计算机科学与技术姓名:刘柯学号:201213030112日期:2014.9.21操作系统课程设计报告一、课程设计内容调用linux系统调用实现多进程的创建、进程间同步与互斥。二、课程设计目的1、加深对进程概念的理解,明确进程和程序的区别2、进一步认识并发执行的实质3、分析进程竞争资源现象,学习解决进程互斥的方法4、了解Linux系统中进程通信的基本原理三、课程设计题目1.进程的创建任务:编写一段程序,使用系统调用fork()创建两个子进程,这样在此程序运行时,在系统中就有一个父进程和两个子进程在活动。让每一个进程在屏幕上显示一个字符:父进程显示字符a,自进程分别显示字符b和字符c。试观察、记录并分析屏幕上进程调度的情况。如果在程序中使用系统调用nice()来改变各进程的优先级,会出现什么现象?程序://文件process1.cpp#includeiostream#includeunistd.h#includesys/types.husingnamespacestd;intmain(){pid_tpid1,pid2;//两个子进程变量操作系统课程设计报告//创建进程pid1if(pid1=fork())//pid1!=0,是父进程{//创建进程pid2if(pid2=fork())//pid2!=0,是父进程,输出'a'cout'a'endl;else//子进程pid2输出'c'cout'c'endl;}else//子进程pid1输出'b'cout'b'endl;return0;}运行结果:从运行结果来看,只出现了acb。并且最先执行了父进程,父进程return之后,两个子进程才开始执行。原因是fork()函数创建进程的时间多于输出一个字符的时间,所以主进程输出字符’a’的时候(输出’a’之后就return了),两个子进程都还在创建当中。而从进程并发执行来看,输出acb和abc都是有可能。2.进程的控制任务:操作系统课程设计报告修改已编制的程序,将每个进程输出一个字符修改为每个进程输出一句话,再观察程序执行时屏幕上出现的现象。并分析出现问题的原因。进一步理解各个进程争夺临界资源的情况。如果在程序中使用系统调用lockf()来给每一个进程加锁,可以实现进程之间的互斥,试观察并分析出现的现象。程序://文件process2.cpp#includeiostream#includeunistd.h#includesys/types.h#includefcntl.husingnamespacestd;intmain(){pid_tpid1,pid2;//两个子进程变量//创建进程pid1if(pid1=fork())//pid1!=0,是父进程{//创建进程pid2if(pid2=fork())//pid2!=0,是父进程{lockf(1,1,0);//上锁coutIamthefatherprocessendl;lockf(1,0,0);//解锁}else//子进程pid2{lockf(1,1,0);coutIamthekidprocess2endl;lockf(1,0,0);}}else//子进程pid1{lockf(1,1,0);coutIamthekidprocess1endl;lockf(1,0,0);}操作系统课程设计报告return0;}运行结果:运行结果和第一题类似,说明使用fork()函数创建进程的速度非常慢,远远多于输出一段字符串的时间。cout输出字符串是连续的,因此字符串内部的字符顺序输出,不会被打乱。但是由于进程并发执行时的调度顺序和多进程抢占处理机的问题,输出字符串的顺序可能会有所不同。另外,不同进程之间不存在共享临界资源(打印机的互斥性已经由操作系统保证),所以加锁和不加锁的效果相同,故此只列出加锁时的运行结果。3.进程的软中断通讯任务:编制一段程序,实现进程的软中断通讯:使用系统调用fork()创建两个子进程;再使用系统调用。signal()让父进程捕捉键盘上来的中断信号(即按Del键);在捕捉到中断信号后,父进程用系统调用kill()向两个子进程发信号;子进程捕捉到信号后分别输出下列信息后终止:childprocess1iskilledbyparent!childprocess2iskilledbyparent!父进程等待两个子进程都终止以后,输出如下信息后终止:parentprocessinkilled!程序流程图:操作系统课程设计报告程序:这段程序处理的难点是让父进程一直保持运行状态来等待中断信号。程序运行都是快速的,往往用户还没来得及发送中断信号,就已经执行完毕了。本程序设置了一个等待标志变量flag。程序开始时,父进程用signal()指定中断处理函数为fun()。然后让flag=1,并定义一个函数waiting()以flag=1为条件无限循环,达到等待的目的。当用户发出中断指令(按DEL键),fun()函数让flag=0。此时waiting()函数不满足flag=1,循环操作系统课程设计报告结束。程序继续向下执行,父进程用kill()向子进程发送信号,并使用wait(0)进入等待。子进程用同样的方式等待父进程发送信号,收到信号并输出字符串后用exit(0)自动结束。当两个子进程都结束后,父进程输出字符串后程序结束。//文件process3.cpp#includeiostream#includeunistd.h#includesys/types.h#includesys/wait.h#includestdlib.h#includesignal.husingnamespacestd;staticintflag;//全局变量flag作为等待标志,“0”表示不等待,“1”表示等待voidfun(intsig)//信号处理函数,收到信号置flag为0{flag=0;}voidwaiting()//自定义等待函数,flag!=0时无限循环{while(flag!=0);}intmain(){pid_tpid1,pid2;//两个子进程变量if(pid1=fork()){if(pid2=fork()){//父进程flag=1;//设置等待标志为“1”signal(SIGINT,fun);//用fun函数处理“DEL”信号coutwaitingthesignal......endl;waiting();//无限循环,直到用户输入信号kill(pid1,2);//向子进程pid1发出信号“2”,该信号可以任意kill(pid2,2);//向子进程pid2发出信号“2”,该信号可以任意wait(0);//等待子进程结束wait(0);//等待子进程结束coutParentProcessisKilled!endl;}操作系统课程设计报告else{//子进程pid2,处理方式同父进程flag=1;signal(2,fun);waiting();coutChildProcess2isKilledbyParent!endl;exit(0);//子进程结束}}else{//子进程pid1,处理方式同父进程flag=1;signal(2,fun);waiting();coutChildProcess1isKilledbyParent!endl;exit(0);//子进程结束}return0;}运行结果:操作系统课程设计报告本段程序用软中断实现了进程间的通信(父进程和子进程)。运行结果显示,两个子进程执行的顺序有先有后,是随机的。在按DEL键之前,程序一直处于等待之中,从图片最后的光标可以看出程序在等待用户输入,并用有友好的方式进行了提醒:waitingthesignal........四、课程设计总结本次实验的程序需要在Linux环境下编程,所以我额外地学习了在windows系统下安装虚拟机模拟Linux环境来编程的方法。在写代码的过程中,以前有些生疏的地方也熟悉了起来,果然还是实践才是检验真理的标准。这次实验我掌握了在Linux系统下编程的方法,了解了fork()、lockf()、signal()、wait()、kill()等系统调用,丰富了我的知识,受益良多。通过本次实验,我了解了进程的管理,通过实现进程的创建、进程的控制,编写一段程序,实现进程的软中断通信。加深了对进程概念的理解,明确进程和程序的区别,进一步认识并发执行的实质。巩固了课本上所学到的知识。