i++>
{
printf("\n进程号No.%d:
\n",i+1>。
p=getpch(PCB>。
printf("\n输入进程名:
">。
scanf("%s",p->name>。
printf("\n输入进程运行时间:
">。
p->ntime=geti(>。
printf("\n">。
p->rtime=0。
p->state='w'。
p->queue=1。
p->etime=TIME。
p->link=NULL。
insert(>。
/*调用insert函数*/
}
}
voiddisp(PCB*pr>/*建立进程现实函数,用于显示当前进程*/
{
printf("\nname\tstate\tqueue\tntime\trtime\t在队列可停留时间\t\n">。
EmxvxOtOco
printf("|%s\t",pr->name>。
printf("|%c\t",pr->state>。
printf("|%d\t",pr->queue>。
printf("|%d\t",pr->ntime>。
printf("|%d\t",pr->rtime>。
printf("|%d\t",pr->etime>。
printf("\n">。
}
voidcheck(>/*建立进程查看函数*/
{
PCB*pr。
printf("\n****当前正在运行的进程是:
%s",ready->name>。
/*显示当前运行的进程*/SixE2yXPq5
disp(ready>。
pr=ready->link。
printf("\n****当前就绪队列状态为:
\n">。
/*显示就绪队列状态*/
while(pr!
=NULL>
{
disp(pr>。
pr=pr->link。
}
}
voidsort(>//调整进程队列
{
if(!
ready->link||ready->queuelink->queue>return。
6ewMyirQFL
p=ready->link。
ready->link=pinsert->link。
pinsert->link=ready。
pinsert=ready。
ready=p。
if(ready&&ready->queue==pinsert->queue>{
findpos(>。
}
}
voidaddnew(>//添加新的进程
{
if(ready->queue!
=1>{
(ready->queue>++。
ready->etime*=2。
ready->state='w'。
sort(>。
/*调用sort函数*/
input(>。
}
else{
input(>。
}
}
voiddestroy(>/*建立进程撤销函数(进程运行结束,撤销进程>*/
{
printf("\n进程[%s]已完成.\n",ready->name>。
p=ready。
ready=ready->link。
free(p>。
if(ready&&ready->queue==pinsert->queue>
findpos(>。
}
voidrunning(>/*建立进程就绪函数(进程运行时间到,置就绪状态>*/
{
(ready->rtime>++。
ready->etime--。
if(ready->rtime==ready->ntime>{
destroy(>。
return。
}elseif(ready->etime==0>{
inttime=2。
(ready->queue>++。
for(inti=2。
i!
=ready->queue。
++i>
time*=2。
ready->etime=time。
ready->state='w'。
sort(>。
/*调用sort函数*/
}
}
voidmain(>
{
charch。
input(>。
while(ready!
=NULL>
{
printf("\nTheexecutename:
%s\n",ready->name>。
ready->state='R'。
check(>。
running(>。
printf("\n按i键添加新进程....按其他任意键继续运行...">。
fflush(stdin>。
ch=getchar(>。
if(ch=='i'||ch=='I'>
addnew(>。
}
printf("\n\n进程已经完成\n">。
getchar(>。
}
计算机学院网络工程专业3班_____组、学号**********
姓名张菲协作者无教师评定_________________
实验题目作业调度
一、实验目的
本实验要求学生模拟作业调度的实现,用高级语言编写和调试一个或多个作业调度的模拟程序,了解作业调度在操作系统中的作用,以加深对作业调度算法的理解。
kavU42VRUs
二、实验内容和要求
1、编写并调度一个多道程序系统的作业调度模拟程序。
作业调度算法:
采用基于先来先服务的调度算法。
可以参考课本中的方法进行设计。
对于多道程序系统,要假定系统中具有的各种资源及数量、调度作业时必须考虑到每个作业的资源要求。
三、实验主要仪器设备和材料
硬件环境:
IBM-PC或兼容机
软件环境:
C语言编程环境
四、实验原理及设计方案
采用多道程序设计方法的操作系统,在系统中要经常保留多个运行的作业,以提高系统效率。
作业调度从系统已接纳的暂存在输入井中的一批作业中挑选出若干个可运行的作业,并为这些被选中的作业分配所需的系统资源。
对被选中运行的作业必须按照它们各自的作业说明书规定的步骤进行控制。
y6v3ALoS89
采用先来先服务算法算法模拟设计作业调度程序。
<1)、作业调度程序负责从输入井选择若干个作业进入主存,为它们分配必要的资源,当它们能够被进程调度选中时,就可占用处理器运行。
作业调度选择一个作业的必要条件是系统中现有的尚未分配的资源可满足该作业的资源要求。
但有时系统中现有的尚未分配的资源既可满足某个作业的要求也可满足其它一些作业的要求,那么,作业调度必须按一定的算法在这些作业中作出选择。
先来先服务算法是按照作业进入输入井的先后次序来挑选作业,先进入输入井的作业优先被挑选,当系统中现有的尚未分配的资源不能满足先进入输入井的作业时,那么顺序挑选后面的作业。
M2ub6vSTnP
(2>假定某系统可供用户使用的主存空间共100k,并有5台磁带机。
3>流程图:
五、结果过程及截图
读取文件jobs.txt来初始化主存,磁带机的个数,并打印出来。
初始时间是9:
00:
按Y运行5分钟:
按Y运行5分钟:
按Y运行5分钟:
多次运行后最后状态:
六、所遇困难的解决以及心得体会
这个实验是花的时间最多的一个实验,第一次做的时候由于理解有些问题,所以做错了。
之后重新做了一遍,收获还是很多的,遇到了很多的细节问题,例如像是时间化成浮点数和浮点数化成时间等一些问题,从中也暴露了自己的编程能力欠缺,之后要多多的写程序。
0YujCfmUCw
七、思考题
1、写出每种算法的调度策略,最后比较各种算法的优缺点。
答:
先来先服务算法是根据作业的进入时间来排序,到达时间短的先运行,优点是实现简单,缺点是运行时间慢。
短作业优先算法是根椐作业的估计运行时间来排序,估计运行时间短的先运行,优点是运行时间快,缺点是实现起来比较复杂。
eUts8ZQVRd
2、选择调度算法的依据是什么?
答:
如果作业要求的速度不高,而且作业比较小型,那就最好用先来先服务算法。
如果作业要求的速度高,作业流程复杂,那就最好用短作业优先算法。
八、源代码
#include
#include
#include
#include
#definegetjcb(>(JCB*>malloc(sizeof(JCB>>
typedefstruct{//资源的总量
intmemory。
inttape。
}RESOURCE。
typedefstructJCB{//作业控制块
charusername[20]。
//用户名
charjobname[10]。
//作业名
charstate。
//作业状态
charatime[5]。
//到达时间
floatrtime。
//运行时间
RESOURCEresource。
//资源数量
structJCB*link。
}JCB。
RESOURCEsource={100,5}。
JCB*pjcb=getjcb(>。
//作业链表头
charnowtime[5]。
//现在时间,初始时间为9:
00
FILE*ignore(FILE*fp>//忽略文件中的空白符
{
if(feof(fp>>returnfp。
charch=fgetc(fp>。
while(!
feof(fp>&&(ch==''||ch==''>>{
ch=fgetc(fp>。
}
//if(!
feof(fp>>returnfp。
fseek(fp,-1,SEEK_CUR>。
returnfp。
}
FILE*findchar(FILE*fp,charc>//在文件中找到一个字符的位置(读取文件时用>sQsAEJkW5T
{
if(feof(fp>>returnfp。
charch=fgetc(fp>。
while(!
feof(fp>&&(ch!
=c>>{
ch=fgetc(fp>。
}
fseek(fp,-1,SEEK_CUR>。
returnfp。
}
voiddestory(>//释放链表所占的内存
{
JCB*p=pjcb->link。
while(pjcb>{
free(pjcb>。
pjcb=p。
if(p>
p=p->link。
}
}
floatstof(char*time>//把时间转化为浮点型数
{
floath=0,m=0。
inti=0。
while(time[i]!
=':
'>{
h=h*10+time[i]-'0'。
i++。
}
i++。
while(time[i]!
='\0'>{
m=m*10+time[i]-'0'。
i++。
}
return(h+m/60>。
}
char*ftos(doubleftime>//把浮点型数值转化为时间
{
inth,m。
h=int(ftime>。
m=int((ftime-h>*60>。
sprintf(nowtime,"%c:
%c%c",h+'0',int(m/10>+'0',int(m%10>+'0'>。
GMsIasNXkA
returnnowtime。
}
floattimesub(char*time1,char*time2>//两个时间相减,得到时间差TIrRGchYzg
{
returnstof(time1>-stof(time2>。
}
voidprint(>//打印输出
{
JCB*p=pjcb->link。
printf("现在时间是%s\n",nowtime>。
printf("现在资源的数量%d\t\t%d\n",source.memory,source.tape>。
7EqZcWLZNX
printf("\t\t\t\t\t\t\t资源要求\n">。
printf("用户名\t作业名\t状态\t到达时间\t运行时间(小时>\t主存(K>\t磁带机\n">。
lzq7IGf02E
while(p>{
printf("%s\t%s\t%c\t%s\t\t\t%.2f\t%d\t%d\n",p->username,p->jobname,p->state,p->atime,p->rtime,p->resource.memory,p->resource.tape>。
zvpgeqJ1hk
p=p->link。
}
}
voidsendsource(>//为作业分配资源
{
JCB*p。
p=pjcb->link。
while(p>{//为到达的作业调度
if(p->state=='W'&&source.memory-p->resource.memory>=0&&source.tape-p->resource.tape>=0>{NrpoJac3v1
p->state='R'。
source.memory-=p->resource.memory。
source.tape-=p->resource.tape。
printf("\n%s\t%s被调入内存\n",p->username,p->jobname>。
1nowfTG4KI
}
p=p->link。
}
}
voidinit(>//初始化,读取文件中的作业信息
{
FILE*fp。
JCB*p=NULL,*q=pjcb。
if((fp=fopen("jobs.txt","r">>==NULL>{
printf("Cannotopenthefile!
">。
exit(1>。
}
rewind(fp>。
fp=findchar(fp,'A'>。
while(!
feof(fp>>{
p=getjcb(>。
fscanf(fp,"%s",p->username>。
fp=ignore(fp>。
fscanf(fp,"%s",p->jobname>。
fp=ignore(fp>。
fscanf(fp,"%c",&p->state>。
fp=ignore(fp>。
fscanf(fp,"%s",p->atime>。
fp=ignore(fp>。
p->rtime=0。
//不初始化则会发生错误,