1581.进程管理系统设计操作系统设计报告.doc
计算机科学与技术学院课程设计报告 ( 2005 2006 学年度 第 一 学期 )课程名称操作系统课程设计项目名称进程管理系统设计姓名学号专业计算机科学与技术班级地点教师一,设计任务与主题我的课程设计标题是“进程调度系统设计”,主要内容是:模拟计算机操作系统的进程调度,加深对进程概念及进程管理各部分内容的理解;熟悉进程管理中主要数据结构的设计及进程调度算法、进程控制机构的实施。要求设计一个允许n个进程并发运行的进程管理模拟系统。该系统包括有简单的进程控制,其进程调度算法可任意选择。每个进程用一个PCB表示,其内容根据具体情况设置,要求运用C或C+作为编程语言。具体要求如下:设计一个模拟进程调度的系统;采用FIFO、SPF和优先级调度算法;自己根据算法需要确定PCB中的数据结构;能够显示进程的运行状态包括进程状态、占用CPU时间、要求服务时间等信息。二,设计方案采用C+编写,首先建立进程的PCB,包括进程名,进程状态,进程运行所需时间,优先级,等待时间(自己定义),再初始化各个进程,名字为空,各个结构为0,预计写三个调度算法,分别用三个函数表示,FIFO(),Superior(),和ShortTask().使用文件方式读入用户进程,包括进程名,状态,时间,优先级,但有关函数不会用,参考了互联网上的某个算法,感觉写得非常好,即是ReadData()函数,尤其是读取进程的函数,值得我学习。在FIFO中,按照读取顺序直接运行,打印进程名和等待时间,计算等待时间用一个嵌套循环,第i个进程的等待时间是它前面所有进程的执行时间,因此用2个循环。计算总的等待时间时,加上所有的等待时间即是。在计算进程的各个完成时间点时,自己运行时间加上等待时间即可。算法如下:void FIFO() int i,j; float total; /定义沸点时间cout<<endl<<"-"<<endl; cout<<"下面输出FIFO算法执行过程(以执行顺序从上到下排列):"<<endl; cout<<"进程名 等待时间"<<endl; for(i=0;i<Num;i+) cout<<pcbi.name<<" "<<pcbi.WaitTime<<endl; for(j=i+1;j<Num;j+) /计算进程等待时间,依次加上后续进程时间 pcbj.WaitTime+=pcbi.time; total=0.0; for(i=0;i<Num;i+) /计算总的等待时间 total+=pcbi.WaitTime; cout<<"总等待时间:"<<total<<" 平均等待时间:"<<total/Num<<endl; for(int m=0;m<Num;m+) /输出进程完成时间点 cout<<"进程"<<pcbm.name<<"第"<<pcbm.time+pcbm.WaitTime<<"时间点完成"<<endl; 在优先调度算法中,大致一样,但是重点是计算优先排列,在此定义一个顺序数组linei,用于存储进程顺序号,首先定义一个当前优先级,用一个FOR循环对进程优先级依次进行比较,凡是数字小的(即优先级高的)就把进程号排在数组前面,每次循环的同时计算等待时间,方法与前面类似,不过把time 改成了PassTime。输出执行过程时,注意把前面的i换成linei,其他的和前面的一样,不在鏊述。算法如下:void Superior() int i,j,p; int PassTime=0; /定义已过时间,方便后面计算等待时间 float total; int lineMAXPCB; /定义调度顺序数组 int NonceSuperior=100; /定义当前优先数级 for(i=0;i<Num;i+) /以优先级高低进行排列 NonceSuperior=100; for(j=0;j<Num;j+) if(pcbj.Done=0)&&(pcbj.Superior<NonceSuperior) /比较优先级高低,高的向前插 p=j; NonceSuperior=pcbj.Superior; /下面计算进程等待时间 linei=p; pcbp.Done=1; pcbp.WaitTime+=PassTime; PassTime+=pcbp.time; /下面输出优先数调度执行过程 cout<<endl<<"-"<<endl; cout<<"下面输出优先级调度执行过程(以执行顺序从上到下排列):"<<endl; cout<<"进程名 等待时间"<<endl; for(i=0;i<Num;i+) cout<<pcblinei.name<<" "<<pcblinei.WaitTime<<endl; total=0.0; /计算总等待时间 for(i=0;i<Num;i+) total+=pcbi.WaitTime; cout<<"总等待时间:"<<total<<" 平均等待时间:"<<total/Num<<endl; for(i=0;i<Num;i+) cout<<"进程"<<pcblinei.name<<"第"<<pcblinei.WaitTime+pcblinei.time<<"时间点完成"<<endl; 在SPF中,和优先调度几乎一样,只是把优先级比较换成了作业时间比较,其他的都一样。而在并行运行中,由于比较简单,在假设磁盘和CPU空间足够下,只需将各个进程运行时间排列就行了。最后是main函数,依次调用,但要注意调用以后要重新初始化,即initial(),以供其他算法使用。三系统及函数原理框图(下一页)结束并行算法Allrun()短作业优先算法ShortTask()FIFO()算法main() 初始化init()读取数据判断是否成功部分重新初始化优先级算法Superior()FIFO()算法否是四论证与实验结果经实践后无错误,结果正确,例如预先在文件中输入:p1 Ready 5 6p2 Ready 8 4p3 Ready 9 2p4 Ready 3 1p5 Ready 7 3运行时输入文件名file.txt(自定义),结果如下:五实验中遇到的主要问题及解决方法1在设计过程中,本来预先在输入时采用边运行边输入,后来为了简便,想采用读取文件的方式输入,但设计时遇到困难,采用教科书上介绍的方法不能完全实现,尤其是怎样以特定的方式读取就是一个问题,很久也没有想出来,最后参考某网友的算法,终于得到了解决,他采用的是另一种文件操作函数,要预先定义文件流,再用fscanf()函数,直接按照要求格式读取,每读取一行,使进程个数变量自加,计算总个数。 代码如下:int ReadData() FILE *fp; /定义文件指针 char fname20; /定义文件名 int i; cout<<"请输入你设置的进程总文件名:" cin>>fname; if(fp=fopen(fname,"r")=NULL) /文件打开函数 cout<<"错误,文件打不开,请检查文件名"<<endl; else while(!feof(fp) /文件读取函数 fscanf(fp,"%s %s %d %d",pcbNum.name,&pcbNum.status,&pcbNum.time,&pcbNum .Superior); Num+; cout<<"读取数据成功"<<endl;cout<<"一共有进程数"<<Num<<"个"<<endl;/输出所读入的数据 cout<<endl; cout<<"下面输出所读入的数据(以到来顺序从上到下排列)"<<endl; cout<<"进程名 进程状态 所需时间 优先级"<<endl; for(i=0;i<Num;i+) cout<<pcbi.name<<" "<<pcbi.status<<" "<<pcbi.time<<" "<<pcbi.Superior<<endl; return 1; return 0 ; 2在进行首次初始化时,给进程取名时也产生了错误,我简单地以为和取整型变量一样,直接赋予,结果有错,这才想起字符串输入不能这样操作,应该COPY,应该有一个函数叫strcpy(),专门用于这种操作,最后解决了。3在进行第一次编译时没有错,以为可以了,运行后结果却不对,主要是计算时间出现问题,而第一个算法却是对的,那可能是后面运行时出了错,用笔仔细算了一下,发现是开始的等待时间就不对,原来在FIFO运算了以后等待时间已变,而后面的运算则需要重新初始化,然后有了initial()函数,代码如下:void initial() int i; for(i=0;i<MAXPCB;i+) pcbi.Done=0; pcbi.WaitTime=0; 4在后两个算法中,要将进程相应的排序才能正确运行,在这里,我的思想是先写一个排序算法,用数组保存进程号,同时计算等待时间,运行时再相应的调出,其实设计算法不难,但在实现时总遇到不少的问题,因为是一个2重循环,写的时候难免出错,甚至一些小错误,由此我认为做什么事都要十分认真,尤其是编程这种工作,错了一个标点符号,结果就完全不一样,还要必须熟悉整个过程,不然是写不出来的。六编译环境及使用说明 WINDOWS 2000,VISUAL C+ 6。0 本程序运行前需先将进程输入文件,运行时再从文件中读取。七参考资料 1.<<面向对象的程序设计语言C+>> 陈志泊,王春玲 人民邮电出版社 2<<计算机操作系统>> 胡志刚,谭长庚 中南大学出版社 3 希赛网中国最大的IT技术/IT管理/IT教育/IT培训/IT咨询资源网站() 附录:源程序#include<stdio.h> #include<string.h> #include<iostream.h> const int MAXPCB=50; /定义最大进程数 /定义进程结构体 typedef struct Node char name20; /进程名 char status10; /进程状态(如规模,大小,日期,由用户自己定义) int time; /进程运行所需时间 int Superior; /进程的优先级数 int Done; /进程完成参数 int WaitTime; /进程等待时间PCB; PCB pcbMAXPCB; int Num; /定义进程个数/初始化函数 void init() int i; for(i=0;i<MAXPCB;i+) strcpy(pcbi.name,"");/预先给进程赋予空名 strcpy(pcbi.status,"Ready"); pcbi.time=0; pcbi.Superior=0; pcbi.Done=0; pcbi.WaitTime=0; Num=0; /读数据函数 int ReadData() FILE *fp; /定义文件指针 char fname20; /定义文件名 int i; cout<<"请输入你设置的进程总文件名:" cin>>fname; if(fp=fopen(fname,"r")=NULL) /文件打开函数 cout<<"错误,文件打不开,请检查文件名"<<endl; else while(!feof(fp) /文件读取函数 fscanf(fp,"%s %s %d %d",pcbNum.name,&pcbNum.status,&pcbNum.time,&pcbNum .Superior); Num+; cout<<"读取数据成功"<<endl;cout<<"一共有进程数"<<Num<<"个"<<endl;/输出所读入的数据 cout<<endl; cout<<"下面输出所读入的数据(以到来顺序从上到下排列)"<<endl; cout<<"进程名 进程状态 所需时间 优先级"<<endl; for(i=0;i<Num;i+) cout<<pcbi.name<<" "<<pcbi.status<<" "<<pcbi.time<<" "<<pcbi.Superior<<endl; return 1; return 0 ; /部分重新初始,以供其他算法使用 void initial() int i; for(i=0;i<MAXPCB;i+) pcbi.Done=0; pcbi.WaitTime=0; /先进先出算法并输出FIFO算法执行过程void FIFO() int i,j; float total; /定义沸点时间 cout<<endl<<"-"<<endl; cout<<"下面输出FIFO算法执行过程(以执行顺序从上到下排列):"<<endl; cout<<"进程名 等待时间"<<endl; for(i=0;i<Num;i+) cout<<pcbi.name<<" "<<pcbi.WaitTime<<endl; for(j=i+1;j<Num;j+) /计算进程等待时间,依次加上后续进程时间 pcbj.WaitTime+=pcbi.time; total=0.0; for(i=0;i<Num;i+) /计算总的等待时间 total+=pcbi.WaitTime; cout<<"总等待时间:"<<total<<" 平均等待时间:"<<total/Num<<endl; for(int m=0;m<Num;m+) /输出进程完成时间点 cout<<"进程"<<pcbm.name<<"第"<<pcbm.time+pcbm.WaitTime<<"时间点完成"<<endl; /优先数调度算法 void Superior() int i,j,p; int PassTime=0; /定义已过时间,方便后面计算等待时间 float total; int lineMAXPCB; /定义调度顺序数组 int NonceSuperior=100; /定义当前优先数级 for(i=0;i<Num;i+) /以优先级高低进行排列 NonceSuperior=100; for(j=0;j<Num;j+) if(pcbj.Done=0)&&(pcbj.Superior<NonceSuperior) /比较优先级高低,高的向前插 p=j; NonceSuperior=pcbj.Superior; /下面计算进程等待时间 linei=p; pcbp.Done=1; pcbp.WaitTime+=PassTime; PassTime+=pcbp.time; /下面输出优先数调度执行过程 cout<<endl<<"-"<<endl; cout<<"下面输出优先级调度执行过程(以执行顺序从上到下排列):"<<endl; cout<<"进程名 等待时间"<<endl; for(i=0;i<Num;i+) cout<<pcblinei.name<<" "<<pcblinei.WaitTime<<endl; total=0.0; /计算总等待时间 for(i=0;i<Num;i+) total+=pcbi.WaitTime; cout<<"总等待时间:"<<total<<" 平均等待时间:"<<total/Num<<endl; for(i=0;i<Num;i+) cout<<"进程"<<pcblinei.name<<"第"<<pcblinei.WaitTime+pcblinei.time<<"时间点完成"<<endl; /短作业优先调度算法void ShortTask() int m,j,p; int PassTime=0; float total; int lineMAXPCB; int NonceShortTask=100; for(m=0;m<Num;m+) NonceShortTask=100; for(j=0;j<Num;j+) if(pcbj.Done=0)&&(pcbj.time<NonceShortTask) p=j; NonceShortTask=pcbj.time; linem=p; pcbp.Done=1; pcbp.WaitTime+=PassTime; PassTime+=pcbp.time; /下面输出短作业优先执行程序 cout<<endl<<"-"<<endl; cout<<"下面输出短作业优先执行过程(以执行顺序从上到下排列):"<<endl; cout<<"进程名 等待时间"<<endl; for(m=0;m<Num;m+) cout<<pcblinem.name<<" "<<pcblinem.WaitTime<<endl; total=0.0; for(m=0;m<Num;m+) total+=pcbm.WaitTime; cout<<"总等待时间:"<<total<<" 平均等待时间:"<<total/Num<<endl; for(m=0;m<Num;m+) cout<<"进程"<<pcblinem.name<<"第"<<pcblinem.WaitTime+pcblinem.time<<"时间点完成"<<endl; void Allrun() cout<<"-"<<endl; cout<<"下面假设磁盘和CPU空间足够,能够并行运行,输出并行运行后的结果"<<endl; cout<<"进程名 所需时间"<<endl; for(int i=0;i<Num;i+) cout<<pcbi.name<<" "<<pcbi.time<<endl; for(int m=0;m<Num;m+) cout<<"进程"<<pcbm.name<<"第"<<pcbm.time<<"时间点完成"<<endl;/主函数 void main() int success;/定义是否成功读取参数 cout<<"*欢迎进入进程调度模拟系统*"<<endl; init(); success=ReadData(); if(success=1) FIFO(); initial(); Superior(); initial(); ShortTask(); Allrun();