魏多FCFSSJF实验报告.docx
《魏多FCFSSJF实验报告.docx》由会员分享,可在线阅读,更多相关《魏多FCFSSJF实验报告.docx(13页珍藏版)》请在冰豆网上搜索。
![魏多FCFSSJF实验报告.docx](https://file1.bdocx.com/fileroot1/2022-12/16/7ea7737d-9b99-4e63-b3ba-eddd1ef32e95/7ea7737d-9b99-4e63-b3ba-eddd1ef32e951.gif)
魏多FCFSSJF实验报告
操
作
系
统
实
验
报
告
学院:
软件学院
班级:
过程控制12-02
姓名:
魏多
学号:
541213470244
目录
1、实验目的:
3
2、问题描述:
3
FCFS算法3
实验程序3
实验结果截图7
测试结果描述7
SJF算法7
实验程序7
实验结果截图11
测试结果描述12
1、实验目的:
通过这次实验,加深对进程概念的理解,进一步掌握进程状态的转变、进程调度的策略及对系统性能的评价方法。
2、问题描述:
假设有n个进程分别在T1,…,Tn时刻到达系统,它们需要的服务
时间分别为S1,…,Sn。
分别采用先来先服务FCFS和短作业优先SJF
进程调度算法进行调度,计算每个进程的完成时间、周转时间和带权周转时间,并且统计n个进程的平均周转时间和平均带权周转时间。
FCFS算法
实验程序
#include
#include
//#include//c里面没有string,因为string是一个类,而c没有类
#include
//usingnamespacestd;
structPCB
{
intProcessReachTime;//标志进程到达时间
charPID[10];//进程ID
//intpriority;//进程优先数,在这里的FCFS没有用
//intchip;//时间片
intneedTime;
intcputime;//进程已经占用CPU的时间
intalltime;//进程还需要运行的时间(当进程运行完毕时,其值为0)
charstate;//进程的状态STATE(为简化起见。
设每个进程处于运行E(excecuting)、就绪R(ready)和完成F(finish)三种状态之一,并假设起始状态都是就绪状态R。
)
structPCB*next;//进程队列指针NEXT(用来将PCB排成队列)等
};
inttime;//用于进程到达时间和需要时间
charstrPID[10];
intnum;
structPCB*start,*startHead,*temp,*newNode;
inttotalTime=0;
intmain()
{
printf("请输入进程数:
");
scanf("%d",&num);
start=(PCB*)malloc(sizeof(PCB));
startHead=(PCB*)malloc(sizeof(PCB));
start=NULL;
startHead=start;
temp=(PCB*)malloc(sizeof(PCB));
temp=startHead;
for(inti=0;i{
startHead=start;
temp=startHead;
newNode=(PCB*)malloc(sizeof(PCB));
//--------------------------
printf("请输入进程ID:
");
scanf("%s",strPID);
strcpy(newNode->PID,strPID);//不能用newNode->PID=strPID;因为PID是一个字符数组newNode->PID是一个常量,不能复制
//--------------------------
printf("请输入进程到达时间:
");
scanf("%d",&time);
newNode->ProcessReachTime=time;
//--------------------------
printf("请输入进程需要时间:
");
scanf("%d",&time);
newNode->needTime=time;
//--------------------------
newNode->state='R';
newNode->next=NULL;
if(i==0)
{
start=newNode;
startHead=start;
}
elseif(i==1)
{
if(start->ProcessReachTime<=newNode->ProcessReachTime)
{
startHead->next=newNode;
}
else
{
newNode->next=startHead;
start=newNode;
}
}
else
{
for(startHead=start;startHead!
=NULL;startHead=startHead->next)
{
temp=startHead;
if(start->ProcessReachTime>newNode->ProcessReachTime)
{
newNode->next=startHead;
start=newNode;
break;
}
elseif(startHead->ProcessReachTime<=newNode->ProcessReachTime&&startHead->next!
=NULL&&startHead->next->ProcessReachTime>newNode->ProcessReachTime)//注意后面两个的顺序,如果顺序调换会发生错误
{
newNode->next=startHead->next;
temp->next=newNode;
break;
}
elseif(startHead->next==NULL)
{
temp->next=newNode;
break;
}
}
}
}
intstartTime=0;//用于记录一个进程开始运行的时间
startHead=start;
for(inti=0;startHead!
=NULL;i++)
{
if(startHead->ProcessReachTime<=i&&startHead->state=='R')
{
startTime=i;//记录开始时间i为astartTime
startHead->state='E';//进程为执行状态
printf("在%d时刻:
",i);
printf("进程%s开始运行\n",startHead->PID);
}
elseif(i-startTimeneedTime&&i-startTime>0&&startHead->state=='E')
{
printf("在%d时刻:
",i);
printf("进程%s正在运行\n",startHead->PID);
}
elseif(i-startTime==startHead->needTime&&startHead->state=='E')
{
startHead->state='F';
printf("在%d时刻:
",i);
printf("进程%s结束运行\n",startHead->PID);
startHead=startHead->next;
i--;//这个很重要,主要在结束时刻是否有进程执行
}
if(startHead==NULL)
{
printf("进程调度结束");
}
}
while
(1);
}
实验结果截图
测试结果描述
假设两个进程编号为001,002
001进程5时刻到达运行3
002进程0时刻到达运行6
先运行002进程6时间段之后运行0013时间段
SJF算法
实验程序
#include
#defineMaxNum100
usingnamespacestd;
structProcess_struct
{
intNumber;//进程编号
charName[MaxNum];//进程名称
intArrivalTime;//到达时间
intServiceTime;//开始运行时间
intFinishTime;//运行结束时间
intWholeTime;//运行时间
intrun_flag;//调度标志
intorder;//运行次序
doubleWeightWholeTime;//周转时间
doubleAverageWT_FCFS,AverageWT_SJF;//平均周转时间
doubleAverageWWT_FCFS,AverageWWT_SJF;//平均带权周转时间
}Process[MaxNum];
intN;//实际进程个数
intSJF();//短作业优先
intSJF()
{//短作业优先算法
inttemp_time=0;//当期那时间
inti=0,j;
intnumber_schedul,temp_counter;//进程编号,当前已执行进程个数
floatrun_time;
run_time=Process[i].WholeTime;
j=1;
while((j{
if(Process[j].WholeTime{
run_time=Process[i].WholeTime;
i=j;
}
j++;
}
//查找下一个被调度的进程
//对找到的下一个被调度的进程求相应的参数
number_schedul=i;
Process[number_schedul].ServiceTime=Process[number_schedul].ArrivalTime;
Process[number_schedul].FinishTime=Process[number_schedul].ServiceTime+Process[number_schedul].WholeTime;
Process[number_schedul].run_flag=1;
temp_time=Process[number_schedul].FinishTime;
Process[number_schedul].order=1;
temp_counter=1;
while(temp_counter{
for(j=0;j{
if((Process[j].ArrivalTime<=temp_time)&&(!
Process[j].run_flag))
{
run_time=Process[j].WholeTime;
number_schedul=j;
break;
}
}
for(j=0;j{
if((Process[j].ArrivalTime<=temp_time)&&(!
Process[j].run_flag))
if(Process[j].WholeTime{
run_time=Process[j].WholeTime;
number_schedul=j;
}
}
//查找下一个被调度的进程
//对找到的下一个被调度的进程求相应的参数
Process[number_schedul].ServiceTime=temp_time;
Process[number_schedul].FinishTime=Process[number_schedul].ServiceTime+Process[number_schedul].WholeTime;
Process[number_schedul].run_flag=1;
temp_time=Process[number_schedul].FinishTime;
temp_counter++;
Process[number_schedul].order=temp_counter;
}return0;
}
intPinput();//进程参数输入
intPoutput();//调度结果输出
voidmain()
{
system("cls");
intoption;
printf("********************主菜单************************\n");
printf("*1使用短作业优先*\n");
printf("*0退出*\n");
printf("**************************************************\n");
//
//system("color1f");
scanf("%d",&option);
switch(option)
{
case0:
printf("运行结束。
\n");
break;
case1:
printf("对进程用短作业优先调度。
\n\n");
Pinput();
SJF();
Poutput();
break;
}
}
intPinput()//进程参数输入
{
inti;
printf("请输入进程个数:
\n");
scanf("%d",&N);
for(i=0;i{
printf("***************************************\n");
printf("请输入一个进程:
\n",i+1);
printf("请输入进程名称:
\n");
scanf("%s",Process[i].Name);
printf("请输入到达时间:
\n");
scanf("%d",&Process[i].ArrivalTime);
printf("请输入服务时间:
\n");
scanf("%d",&Process[i].WholeTime);
Process[i].ServiceTime=0;
Process[i].FinishTime=0;
Process[i].WeightWholeTime=0;
Process[i].order=0;
Process[i].run_flag=0;
system("cls");
}return0;
}
intPoutput()//调度结果输出
{
inti;
floatturn_round_time=0,f1,w=0;
printf("进程名称到达T运行T开始运行T结束T执行顺序周转T带权周转T\n");
for(i=0;i{
Process[i].WeightWholeTime=Process[i].FinishTime-Process[i].ArrivalTime;
f1=Process[i].WeightWholeTime/Process[i].WholeTime;
turn_round_time+=Process[i].WeightWholeTime;
w+=f1;
printf("时刻%d:
",Process[i].ServiceTime,Process[i].Name);
printf("%s%d%d%d%d%d%f%f\n",Process[i].Name,Process[i].ArrivalTime,Process[i].WholeTime,Process[i].ServiceTime,Process[i].FinishTime,Process[i].order,Process[i].WeightWholeTime,f1);
}
printf("average_turn_round_timer=%f\n",turn_round_time/N);
printf("weight_average_turn_round_timer=%f\n",w/N);
return0;
}
实验结果截图
测试结果描述
假设有3个进程001,002,003
进程1:
0时刻到达,运行5
进程2:
2时刻到达,运行3
进程3:
3时刻到达,运行1
当进程1进入时,还没有其它进程所以先处理进程1,在处理进程1期间进入的进程2,进程3,因为进程3的运行时间短,所以先处理进程3,最后处理进程2。
实验心得
先来先服务算法:
该算法是根据进程到达的时间来决定哪个进程先执行,进程一旦执行,就一直运行到完成或发生某事件而阻塞才放弃处理机。
当进程调度中采用该算法是,系统按照作业到达的先后次序进行调度算法容易实现。
但效率不高,只顾及作业等候时间,没考虑作业要求服务时间的长短。
因此优待了长作业而不利于短作业。
短作业优先算法:
对FCFS算法的改进,其目标是减少平均周转时间,该算法是根据进程的服务时间长短来判断哪个进程先执行,当一个进程执行完后,根据进程的到达情况将进程按照其服务时间进行排序并放入就绪队列中。