操作系统课程设计进程调度的模拟实现.docx
《操作系统课程设计进程调度的模拟实现.docx》由会员分享,可在线阅读,更多相关《操作系统课程设计进程调度的模拟实现.docx(28页珍藏版)》请在冰豆网上搜索。
操作系统课程设计进程调度的模拟实现
课程设计
题目 进程调度算法模拟编程
学生姓名学号
专业计算机科学与技术 班级
指导教师
完成日期2012年12月18日
进程调度的模拟实现
摘要:
进程管理是操作系统中的重要功能,用来创建进程、撤消进程、实现进程状态转换,它提供了在可运行的进程之间复用CPU的方法。
在进程管理中,进程调度是核心,因为在采用多道程序设计的系统中,往往有若干个进程同时处于就绪状态,当就绪进程个数大于处理器数目时,就必须依照某种策略决定哪些进程优先占用处理器。
本文通过两种算法模拟实现了进程之间的调度。
关键词:
进程创建,先来先服务,优先级调度。
一.前言
在操作系统中,调度的实质是一种资源分配,调度算法即指:
根据系统的资源分配策略所规定的资源分配算法。
对于不同的系统和系统目标,通常采用不同的调度算法,如在批处理系统中,为照顾为数众多的短作业,采用短作业有限调度算法;在分时系统中,为保证系统具有合理的响应时间,采用轮转法进行调度。
采用算法时,则要考虑多方面因素,以便达到最佳效果。
做好这个课程设计,有利于加深对操作系统进程调度知识的理解。
二.系统总体框架设计
本程序采用两种算法(最高优先级数优先的调度算法和先来先服务算法)对多个进程进行调度,每个进程有三个状态,初始状态为就绪状态。
最高优先级数优先的调度算法中,程序的某进程运行时间以时间片为单位计算。
各进程的优先数或轮转时间数以及进程需运行的时间片数的初始值均由用户给定。
在优先级数优先的调度算法中,优先级数的值设计为100与运行时间的差值,即Pro_time-process->needtime。
进程每执行一次,优先数减3,CPU时间片数加1,进程还需要的时间片数减1。
对于遇到优先数一致的情况,采用先来先服务策略解决。
程序设计组成框图
数据项
作用
pro_name
进程名称
time_submit
进程创建时刻
pro_id
进程号,当进程有相同名称时,用来区分进程
time_start
进程启动时刻
time_exe
进程要求运行时间
time_end
进程结束的时刻
pro_priority
进程优先级
图1-2 进程控制块
CpuModel类成员
作用
Cpurun()
Cpu模拟运行函数
CreatePcb()
进程创建函数
ShowPcb()
进程显示函数
PriModel()
实现优先级调度算法
FcfsModel()
实现先来先服务算法
pcbnum
进程数量
freetime
Cpu空闲时间
allturn
总周转时间
allaver
总带权周转时间
PcbList[]
进程就绪队列的实现
图1-3CpuModel类
程序流程图
1.可强占优先调度算法实现过程流程图:
2先来先服务调度算法实现过程流图
3.数据结构设计
1.设计创建进程的结构类型定义和结构变量说明struct ProcessPcb,定义PCB相关变量:
ProcessPcb(){next=NULL;}
charpro_name[20];//进程的名字
ﻩinttime_submit; //提交时间,从时间为1开始计时
inttime_exe; //进程所需的运行时间
ﻩint pro_id; //进程ID(系统生成)
ﻩint pro_priority;//进程优先级
ﻩinttime_start;//开始执行的时间
ﻩint time_end; //结束的时间
ﻩ
int time_wait; //等待的时间
ﻩint pro_state;//进程的状态 (就绪,执行,完成)
int time_left;//还需多少时间单位,初始化为所需的执行时间
inttime_turn;ﻩ//周转时间
ﻩdouble time_aver;//带权周转时间
2.创建PCB类classCpuModel,定义程序中使用的各函数:
CpuModel{
CpuModel(){pcbnum=0;}
voidcpurun(); //cpu模拟运行函数
ﻩbool GetPcb(); //进程输入函数
ﻩvoidShowPcb(); //将输入的进程展示出来
voidPriModel();//可强占的优先进程调度模式
void FcfsModel(); //先到先服务调度模式
ProcessPcbPcbList[100];ﻩ//按提交时间排的未就绪进程队列()
}
4.测试结果及分析
1.开始运行,显示:
2.输入进程数,各进程属性:
关于提交时间执行时间等,将检测输入是否数字,不是数字即退出程序。
3.显示已创建的各进程及其属性:
此处的优先级数,是用100减去执行时间。
对于优先级数相同,则默认FIFO。
4.测试可强占的优先进程调度:
一次调度完成,将计算此次运行中CPU的利用率。
5.先到先服务调度算法运行情况:
6.选择5,回车,退出程序。
五.设计心得
在学完操作系统课程之后,一直对进程调度这一块不是很理解,借着做课程设计的机会,我就选择了进程调度模拟编程这个题目,打算在做课程设计的过程中好好的再学习一下这块的知识。
我在做课程设计的过程中,遇到了许多的问题,通过请教同学,上网查资料等途径一一解决。
通过这次操作系统的课程设计,我研究了进程调度的相关知识,加深了对进程调度的理解。
课程设计和平时的实验课比较起来有很大的差距,实验课只是将这一章的一部分内容练习操作一遍,而课程设计需要的是他们综合起来的东西,这要更难一些。
总体来说我认为操作系统这门学科在计算机科学当中是非常重要的,这次操作系统的课程设计收获颇丰,复习了许多东西,也从新学会了许多东西,我想这也许就是课程设计的最终目的吧。
参考文献
[1]刘振安、刘燕君著.《C++程序设计课程设计》.北京:
机械工业出版社,2004
[2][美]AbrahamSilberschatz,Peter BaerGalvin,Greg Gagne著.郑扣根译. 操作系统概念(第六版). 北京:
高等教育出版社,2004
[3]陈向群,向勇等.Windows操作系统原理(第二版).北京:
机械工业出版社,2004.
[4]费翔林,李敏,叶保留等.Linux操作系统实验教程.北京:
高等教育出版社,2009
附录:
#include
#include
#include <string>
#include#include<malloc.h>
using namespace std;
//进程的状态
#defineUNREADY0 //未就绪
#define READY1 //就绪
#defineEXECUTE2 //执行
#defineEND3 //完成
//进程的PCB结构类型定义和结构变量说明
structProcessPcb
{
ProcessPcb()
ﻩ{
ﻩnext=NULL;
ﻩﻩ}
char pro_name[20]; //进程的名字
inttime_submit; //提交时间,从时间的1开始计时
inttime_exe; //进程所需的运行时间
int pro_id; //进程ID(系统生成)
int pro_priority;//进程优先级
inttime_start; //开始执行的时间
inttime_end ; //结束的时间
int time_wait; //等待的时间
intpro_state; //进程的状态(就绪,执行,完成)
ﻩinttime_left; //还需多少时间单位,初始化为所需的执行时间
inttime_turn ; //周转时间
ﻩdoubletime_aver ; //带权周转时间
ProcessPcb *next;
};
//封装CPU调度与分配程序模块。
进程类
class CpuModel
{
ﻩpublic:
ﻩCpuModel()
ﻩﻩﻩ{
pcbnum=0;
ﻩ}
ﻩﻩﻩvoidcpurun();//cpu模拟运行函数
ﻩﻩboolCreatePcb(); //进程输入函数
ﻩvoidShowPcb(); //将输入的进程展示出来
ﻩﻩvoidPriModel(); //可强占的优先进程调度模式
ﻩvoid FcfsModel(); //先到先服务调度模式
ﻩ
ﻩprivate:
ﻩﻩ
ﻩProcessPcbPcbList[100];ﻩ //按提交时间排的未就绪进程队列
ﻩﻩintpcbnum;//进程数量
ﻩﻩintfreetime; //cpu空闲时间
ﻩﻩintallturn; //总周转时间
ﻩfloat allaver ; //总带权周转时间
};
#include
//cpu模拟运行函数
voidCpuModel:
:
cpurun()
{
intchoose=0 ;
while
(1)
{
ﻩ
cout<<"*** 主菜单 ***"<ﻩﻩcout<<"----------------------------------"<<endl;
ﻩcout<<"***1:
创建进程 ***"<ﻩcout<<"*** 2:
显示已创建的进程 ***"<<endl;
ﻩﻩﻩcout<<"*** 3:
可强占的优先进程调度***"<ﻩcout<<"*** 4:
先到先服务调度 ***"<<endl;
ﻩﻩcout<<"*** 5:
退出系统 ***"<ﻩﻩcout<<"\n*** 请选择 :
" ;ﻩ
ﻩ
ﻩﻩcin>>choose ;
ﻩﻩﻩcout<<endl ;
switch(choose)
{
ﻩ
ﻩﻩﻩcase1:
ﻩ
ﻩﻩCreatePcb(); //创建进程
ﻩﻩﻩbreak;
ﻩﻩﻩ
ﻩﻩcase2:
ﻩ
ﻩﻩﻩShowPcb(); //显示已创建的进程
ﻩﻩﻩbreak;
ﻩﻩﻩﻩ
ﻩﻩﻩcase3:
ﻩ
ﻩﻩﻩ
ﻩﻩﻩPriModel(); //可强占的优先进程方式
break;
ﻩﻩcase4:
ﻩ
ﻩﻩﻩFcfsModel();//先到先服务调度方式
break;
ﻩﻩ
case5:
ﻩﻩ
ﻩﻩﻩreturn; //结束程序
}
ﻩﻩcout< }
}
//按进程提交时间排序的比较函数
boolcmp(ProcessPcb a,ProcessPcbb)
{
if(a.time_submit<b.time_submit)
returntrue;
return false;
}
//判断是否数字
intisnumber(chara[])
{
intlen=strlen(a);
inti,num=0;
if(a[0]>'0'&&a[0]<='9')
num=a[0]-'0';
else return -1;
for(i=1;i {
if(a[i]>='0'&&a[i]<='9')
num=num*10+a[i]-'0';
elsereturn-1;
}
return num;
}
//进程输入函数
boolCpuModel:
:
CreatePcb()
{
charnum[10];
cout<<"\n***请输入你想建立的进程个数:
";
cin>>num; //输入进程个数
ﻩ
ﻩpcbnum=isnumber(num);
if(pcbnum<=0)
{
ﻩ cout<<"***输入有错***\n";
ﻩreturn0;
}
ﻩﻩinti;
for(i=0;i {
ﻩ
ﻩﻩcout<<"***请依次输入第"<
ﻩﻩcout<<"*******名字:
";
ﻩcin>>PcbList[i].pro_name ;
ﻩﻩcout<<"***提交时间:
";
ﻩcin>>num;
PcbList[i].time_submit=isnumber(num);
ﻩﻩﻩif(PcbList[i].time_submit<=0)
ﻩﻩﻩ{
ﻩcout<<"***输入有错***\n";
ﻩﻩreturn 0;
ﻩ}
ﻩﻩcout<<"***执行时间:
";
cin>>num;
PcbList[i].time_exe=isnumber(num);
ﻩif(PcbList[i].time_exe<=0)
ﻩ{
ﻩﻩﻩcout<<"***输入有错***\n";
ﻩﻩreturn0;
ﻩ}ﻩﻩ
ﻩﻩ
ﻩPcbList[i].time_left=PcbList[i].time_exe; //设置剩余执行时间
PcbList[i].pro_state=UNREADY; //设置状态为未就绪
PcbList[i].pro_priority=100-PcbList[i].time_exe; //设置优先级,优先级=100-执行时间
ﻩﻩcout< }
ﻩ sort(PcbList,PcbList+pcbnum,cmp); //按提交时间排序
for(i=0;i<pcbnum;i++)
ﻩPcbList[i].pro_id=i+1; //设置Id,根据提交时间
return1;
}
//展示所需执行进程信息
voidCpuModel:
:
ShowPcb()
{
inti;
cout<<"\n***所需执行的进程信息如下***\n";
for(i=0;i<pcbnum;i++)
cout<<"进程编号:
"<<PcbList[i].pro_id<<" 进程名字:
"
<"< <<" 执行时间:
"<"
<
cout<}
//可强占的优先进程调度模式
voidCpuModel:
:
PriModel()
{
cout<<"********可强占的优先进程调度过程如下********\n";
freetime=0; //初始化系统空闲时间为0
int time=0; //时间
intnextid=0;
intpnum=0; //已就绪进程数目
ProcessPcb *head; //就绪队列
ProcessPcb*pcb,*pcb1,*pcb2;
ﻩhead=(ProcessPcb*)malloc(sizeof(ProcessPcb));
head->next=NULL; //head指针不用,head->next开始为就绪队列
ﻩ//模拟cpu开始工作
while(head->next!
=NULL||pnum
{
ﻩﻩSleep(1000);
time++; //时间片为1
ﻩﻩcout<<"*Time:
第"<ﻩﻩ// 进程就绪(查看未就绪的进程中在该时间片是否可以进入就绪队列)
ﻩﻩwhile(pnumﻩﻩ{
ﻩﻩpcb=(ProcessPcb*)malloc(sizeof(ProcessPcb));
ﻩﻩﻩ*pcb=PcbList[pnum++];
ﻩﻩ
ﻩﻩﻩ//进入就绪队列
ﻩﻩﻩpcb->next=head->next; //插在head之后
head->next=pcb;
}
ﻩ
ﻩ//查找在time时间片应该运行的进程
if(head->next==NULL)
{
ﻩcout<<" 没有可运行的进程"< freetime++;
}
else
{
ﻩﻩﻩpcb2=head;
pcb=head->next;
pcb1=head->next;
ﻩﻩﻩ//查找当前优先级最高的就绪进程
ﻩﻩﻩwhile(pcb1->next!
=NULL)
{
ﻩﻩif(pcb->pro_priority<=pcb1->next->pro_priority)
{
ﻩﻩﻩﻩﻩpcb2=pcb1;
ﻩﻩﻩﻩﻩpcb=pcb1->next;
}
ﻩﻩﻩpcb1=pcb1->next;
}
ﻩﻩ//运行优先级最高的进程
ﻩ
ﻩif(pcb->time_left==pcb->time_exe) //该进程是否已开始
{
ﻩpcb->time_start=time; //设置开始时间
ﻩ pcb->pro_state=EXECUTE; //设置状态为执行
}
ﻩ
ﻩﻩpcb->pro_priority=pcb->pro_priority-3;//优先级数减3
pcb->time_left--; //剩余执行时间减去时间片1
ﻩ
ﻩﻩﻩ//打印该进程信息
cout<<" 进程编号:
"<<pcb->pro_id<<"进程名字:
"
ﻩ<<pcb->pro_name<<"提交时间:
"
< "<<pcb->time_exe
<<"\n开始时间:
"<<pcb->time_start
<<" 还剩时间:
"<<pcb->time_left<<"优先级数:
"
<<pcb->pro_priority<ﻩﻩﻩ
ﻩﻩ//该进程是否执行结束
ﻩﻩﻩif(pcb->time_left==0)
{
ﻩﻩﻩpcb2->next=pcb2->next->next;//将其在就绪队列中出列
pcb->time_end=time; //设置结束时间
pcb->time_turn=pcb->time_end-pcb->time_submit+1;
//计算周转时间
pcb->time_aver=pcb->time_turn/(double)pcb->time_exe;
ﻩﻩﻩﻩﻩﻩ//计算带权周转时间
pcb->pro_state=END;
cout<<"\n进程"<<pcb->pro_id<<"运行结束:
"<<"\n进程名字:
"
<<pcb->pro_name<<"提交时间:
"
ﻩﻩﻩﻩ<<pcb->time_submit<<" 执行时间:
"
<time_exe<<" 开始时间:
"
<time_start
ﻩ <<" 结束时间:
"<time_end<<"\nﻩ周转时间:
"
<time_turn<<"带权周转时间:
"
<time_aver<ﻩﻩﻩﻩ}
ﻩﻩ}
}
ﻩ//模拟CPU工作结束
ﻩ cout<<"\n所有进程运行完毕!
"< double c=(time-freetime)/(do