一、实验目的
用高级语言完成一个进程调度程序,以加深对进程的概念及进程调度算法的理解。
二、实验要求
设计一个有 N个进程并发执行的进程调度模拟程序。
1.模拟进程数据的生成,允许用户选择输入每个进程所需运行时间,进程的运行时间以时间片为单位。
2. 模拟调度程序的功能
2.1 按照模拟数据的到达时间和所需运行时间,能分别执行以下调度算法。
FCFS
SJ
HRRN
RR
2.2 显示每种算法下各进程的调度执行顺序。
2.3计算各进程的开始执行时间,各作业的完成时间,周转时间和带权周转时间(周转系数)。
三、实验说明
1) 先来先服务(FCFS)调度算法,即按作业到达的先后次序进行调度。总是首先调度在系统中等待时间最长的作业。
2) 短作业优先 (SJF) 调度算法,优先调度要求运行时间最短的作业。
3) 响应比高者优先(HRRN)调度算法,为每个作业设置一个优先权(响应比),调度之前先计算各作业的优先权,优先数高者优先调度。RP (响应比)= 作业周转时间 / 作业运行时间=1+作业等待时间/作业运行时间。
4) 时间片轮转(RR)调度算法:调度程序每次把CPU分配给就绪队列首进程使用一个时间片,就绪队列中的每个进程轮流地运行一个时间片。当这个时间片结束时,强迫一个进程让出处理器,让它排列到就绪队列的尾部,等候下一轮调度。
四、程序代码:
#include<stdio.h>
#define time int
#define max 24
typedef struct queue{
char name;
int intime;
int needtime;
int runningtime;
float priority;
int waitingtime;
char state;
int starttime;
int finishtime;
float turntime;
float turnnumber;
}PCB;
int n;
int ptime;
PCB pcb[max];
void addprocess(int n){
int i;
for(i=0;i<n;i++){
printf("\n请输入进程名:");
scanf("%s", &pcb[i].name);
printf("\n请输入进程的优先级:");
scanf("%f", &pcb[i].priority);
printf("\n请输入进程的所需时间:");
scanf("%d", &pcb[i].needtime);
pcb[i].intime=i;
pcb[i].state='W';//将进程的状态初始化为等待态
pcb[i].runningtime=0;
}
}
void sort(){
int i,j;
PCB temp;
//通过排序将优先级最高的进程排到最前面
for (i=0;i<n-1;i++)
{
for (j=n-2;j>=i;j--)
{
if (pcb[j+1].priority>pcb[j].priority)
{
temp=pcb[j];
pcb[j]=pcb[j+1];
pcb[j+1]=temp;
}
}
}
if (pcb[0].state!='F')
{
pcb[0].state='R'; //将优先级最高的状态置为运行
}
}
void Print(){
int i;
printf("\n 进程名 优先级 到达时间 需要时间 已用时间 进程状态 \n");
for (i=0;i<n;i++)
{ printf("%7s%12f%10d%10d%10d%10c\n",&pcb[i].name,pcb[i].priority,
pcb[i].intime,pcb[i].needtime,pcb[i].runningtime,pcb[i].state);
}
}
void Print1(){
int i;
printf("\n 进程名 完成时间 开始的时间 周转时间 周转系数 \n");
for (i=0;i<n;i++)
{ printf("%7s%10d%9d%20f%20f%\n",&pcb[i].name,pcb[i].finishtime,pcb[i].starttime,
pcb[i].turntime,pcb[i].turnnumber);
}
}
void RRattemper() //调度
{
int i=0,j=0;
do{
if(i==n){
i=0;
}
if ((pcb[i].needtime-pcb[i].runningtime)>ptime)
{
pcb[i].runningtime=pcb[i].runningtime+ptime; //已用时间加时间片
pcb[i].state='W';
i++;
}
else
{
if(i==n){
i=0;
}
pcb[i].runningtime=pcb[i].needtime;//已用时间等于需要时间
pcb[i].state='F'; //完成进程,将状态置为完成
if(i==0){
pcb[i].waitingtime=0;
}else{
pcb[i].waitingtime=pcb[i-1].needtime+pcb[i-1].waitingtime;
}
pcb[i].starttime=pcb[i].waitingtime;
pcb[i].finishtime=pcb[i].waitingtime+pcb[i].runningtime;
pcb[i].turntime=(float)pcb[i].finishtime-pcb[i].intime;
pcb[i].turnnumber=(float)pcb[i].turntime/pcb[i].needtime;
i++;
if(i==n){
i=0;
}
if(pcb[i].state=='F'){
j++;
}
}
Print();
}while(j<n);
Print1();
}
void FCFSattemper()
{
int i=0;
pcb[0].state='R'; //将最先到达的状态置为运行
do{
if(pcb[i].state=='R'){
pcb[i].runningtime=pcb[i].needtime;
if(i==0){
pcb[i].waitingtime=0;
}else{
pcb[i].waitingtime=pcb[i-1].needtime+pcb[i-1].waitingtime;
}
pcb[i].starttime=pcb[i].waitingtime;
pcb[i].finishtime=pcb[i].waitingtime+pcb[i].runningtime;
pcb[i].turntime=(float)pcb[i].finishtime-pcb[i].intime;
pcb[i].turnnumber=(float)pcb[i].turntime/pcb[i].needtime;
pcb[i].state='F';
i++;
pcb[i].state='R';
}
}while(pcb[n].state!='F');
Print();
Print1();
}
void SJattemper()
{
int i,j;
PCB temp;
//通过排序将时间最少的进程排到最前面
for (i=0;i<n-1;i++)
{
for (j=n-2;j>=i;j--)
{
if (pcb[j+1].needtime<pcb[j].needtime)
{
temp=pcb[j];
pcb[j]=pcb[j+1];
pcb[j+1]=temp;
}
}
}
pcb[0].state='R'; //将时间最少的状态置为运行
i=0;
do{
if(pcb[i].state=='R'){
pcb[i].runningtime=pcb[i].needtime;
if(i==0){
pcb[i].waitingtime=0;
}else{
pcb[i].waitingtime=pcb[i-1].needtime+pcb[i-1].waitingtime;
}
pcb[i].starttime=pcb[i].waitingtime;
pcb[i].finishtime=pcb[i].waitingtime+pcb[i].runningtime;
pcb[i].turntime=(float)pcb[i].finishtime-pcb[i].intime;
pcb[i].turnnumber=(float)pcb[i].turntime/pcb[i].needtime;
pcb[i].state='F';
i++;
pcb[i].state='R';
}
}while(pcb[n].state!='F');
Print();
Print1();
}
void HRRNattemper()
{
int i,j,k=1;
PCB temp;
sort();
pcb[0].runningtime=pcb[0].needtime;
pcb[1].waitingtime=pcb[0].needtime;
pcb[0].state='F';
for(i=1;i<n;i++){
pcb[i].runningtime=pcb[i].needtime;
pcb[i].priority=1+pcb[i].waitingtime/pcb[i].runningtime;
pcb[i+1].waitingtime=pcb[i].needtime+pcb[i].waitingtime;
}
for (i=1;i<n-1;i++)
{
for (j=n-2;j>=i;j--)
{
if (pcb[j+1].priority>pcb[j].priority)
{
temp=pcb[j];
pcb[j]=pcb[j+1];
pcb[j+1]=temp;
}
}
}
for(i=1;i<n;i++){
pcb[i].runningtime=0;
}
pcb[1].state='R';
do{
if(pcb[k].state=='R'){
pcb[k].runningtime=pcb[k].needtime;
pcb[k].runningtime=pcb[k].needtime;
if(k==0){
pcb[k].waitingtime=0;
}else{
pcb[k].waitingtime=pcb[k-1].needtime+pcb[k-1].waitingtime;
}
pcb[k].starttime=pcb[k].waitingtime;
pcb[k].finishtime=pcb[k].waitingtime+pcb[k].runningtime;
pcb[k].turntime=(float)pcb[k].finishtime-pcb[k].intime;
pcb[k].turnnumber=(float)pcb[k].turntime/pcb[k].needtime;
pcb[k].state='F';
k++;
pcb[k].state='R';
}
}while(pcb[n].state!='F');
Print();
Print1();
}
int choose(){
int number;
printf("\n选择FCFS算法的请输入1:\n");
printf("\n选择SJ算法的请输入2:\n");
printf("\n选择HRRN算法的请输入3:\n");
printf("\n选择RR算法的请输入4:\n");
printf("\n结束请输入0:\n");
scanf("%d",&number);
return number;
}
main(){
int chose;
n=0;
printf("请输入进程数:");
scanf("%d", &n);
addprocess(n);
Print();
chose=choose();
do{
if(chose==1){FCFSattemper(); chose=choose();}
if(chose==2){SJattemper(); chose=choose();}
if(chose==3){HRRNattemper(); chose=choose();}
if(chose==4){printf("请输入时间片的值:");
scanf("%d",&ptime);RRattemper(); chose=choose();}
if(chose==0){break;}
}while(1);
}
五、程序代码的简单说明
(1)、定义一个进程控制块PCB:
typedef struct queue{
char name;
int intime;
int needtime;
int runningtime;
float priority;
int waitingtime;
char state;
int starttime;
int finishtime;
float turntime;
float turnnumber;
}PCB;
(2)、程序的主函数:
main(){
int chose;
n=0;
printf("请输入进程数:");
scanf("%d", &n);
addprocess(n);
Print();
chose=choose();
do{
if(chose==1){FCFSattemper(); chose=choose();}
if(chose==2){SJattemper(); chose=choose();}
if(chose==3){HRRNattemper(); chose=choose();}
if(chose==4){printf("请输入时间片的值:");
scanf("%d",&ptime);RRattemper(); chose=choose();}
if(chose==0){break;}
}while(1);
}
(3)、输入进程的函数:
void addprocess(int n){
int i;
for(i=0;i<n;i++){
printf("\n请输入进程名:");
scanf("%s", &pcb[i].name);
printf("\n请输入进程的优先级:");
scanf("%f", &pcb[i].priority);
printf("\n请输入进程的所需时间:");
scanf("%d", &pcb[i].needtime);
pcb[i].intime=i;
pcb[i].state='W';//将进程的状态初始化为等待态
pcb[i].runningtime=0;
}
}
(4)算法选择的函数:
int choose(){
int number;
printf("\n选择FCFS算法的请输入1:\n");
printf("\n选择SJ算法的请输入2:\n");
printf("\n选择HRRN算法的请输入3:\n");
printf("\n选择RR算法的请输入4:\n");
printf("\n结束请输入0:\n");
scanf("%d",&number);
return number;
}
(5)、先来先服务(FCFS)调度算法:
void FCFSattemper()
{
int i=0;
pcb[0].state='R'; //将最先到达的状态置为运行
do{
if(pcb[i].state=='R'){
pcb[i].runningtime=pcb[i].needtime;
if(i==0){
pcb[i].waitingtime=0;
}else{
pcb[i].waitingtime=pcb[i-1].needtime+pcb[i-1].waitingtime;
}
pcb[i].starttime=pcb[i].waitingtime;
pcb[i].finishtime=pcb[i].waitingtime+pcb[i].runningtime;
pcb[i].turntime=(float)pcb[i].finishtime-pcb[i].intime;
pcb[i].turnnumber=(float)pcb[i].turntime/pcb[i].needtime;
pcb[i].state='F';
i++;
pcb[i].state='R';
}
}while(pcb[n].state!='F');
Print();
Print1();
}
(6)、短作业优先 (SJF) 调度算法:
void SJattemper()
{
int i,j;
PCB temp;
//通过排序将时间最少的进程排到最前面
for (i=0;i<n-1;i++)
{
for (j=n-2;j>=i;j--)
{
if (pcb[j+1].needtime<pcb[j].needtime)
{
temp=pcb[j];
pcb[j]=pcb[j+1];
pcb[j+1]=temp;
}
}
}
pcb[0].state='R'; //将时间最少的状态置为运行
i=0;
do{
if(pcb[i].state=='R'){
pcb[i].runningtime=pcb[i].needtime;
if(i==0){
pcb[i].waitingtime=0;
}else{
pcb[i].waitingtime=pcb[i-1].needtime+pcb[i-1].waitingtime;
}
pcb[i].starttime=pcb[i].waitingtime;
pcb[i].finishtime=pcb[i].waitingtime+pcb[i].runningtime;
pcb[i].turntime=(float)pcb[i].finishtime-pcb[i].intime;
pcb[i].turnnumber=(float)pcb[i].turntime/pcb[i].needtime;
pcb[i].state='F';
i++;
pcb[i].state='R';
}
}while(pcb[n].state!='F');
Print();
Print1();
}
(7)、响应比高者优先(HRRN)调度算法:
void HRRNattemper()
{
int i,j,k=1;
PCB temp;
sort();
pcb[0].runningtime=pcb[0].needtime;
pcb[1].waitingtime=pcb[0].needtime;
pcb[0].state='F';
for(i=1;i<n;i++){
pcb[i].runningtime=pcb[i].needtime;
pcb[i].priority=1+pcb[i].waitingtime/pcb[i].runningtime;
pcb[i+1].waitingtime=pcb[i].needtime+pcb[i].waitingtime;
}
for (i=1;i<n-1;i++)
{
for (j=n-2;j>=i;j--)
{
if (pcb[j+1].priority>pcb[j].priority)
{
temp=pcb[j];
pcb[j]=pcb[j+1];
pcb[j+1]=temp;
}
}
}
for(i=1;i<n;i++){
pcb[i].runningtime=0;
}
pcb[1].state='R';
do{
if(pcb[k].state=='R'){
pcb[k].runningtime=pcb[k].needtime;
pcb[k].runningtime=pcb[k].needtime;
if(k==0){
pcb[k].waitingtime=0;
}else{
pcb[k].waitingtime=pcb[k-1].needtime+pcb[k-1].waitingtime;
}
pcb[k].starttime=pcb[k].waitingtime;
pcb[k].finishtime=pcb[k].waitingtime+pcb[k].runningtime;
pcb[k].turntime=(float)pcb[k].finishtime-pcb[k].intime;
pcb[k].turnnumber=(float)pcb[k].turntime/pcb[k].needtime;
pcb[k].state='F';
k++;
pcb[k].state='R';
}
}while(pcb[n].state!='F');
Print();
Print1();
}
(8)时间片轮转(RR)调度算法:
void RRattemper() //调度
{
int i=0,j=0;
do{
if(i==n){
i=0;
}
if ((pcb[i].needtime-pcb[i].runningtime)>ptime){
pcb[i].runningtime=pcb[i].runningtime+ptime; //已用时间加时间片 pcb[i].state='W';
i++;
}
else
{
if(i==n){
i=0;
}
pcb[i].runningtime=pcb[i].needtime;//已用时间等于需要时间 pcb[i].state='F'; //完成进程,将状态置为完成
if(i==0){
pcb[i].waitingtime=0;
}else{
pcb[i].waitingtime=pcb[i-1].needtime+pcb[i-1].waitingtime;
}
pcb[i].starttime=pcb[i].waitingtime;
pcb[i].finishtime=pcb[i].waitingtime+pcb[i].runningtime;
pcb[i].turntime=(float)pcb[i].finishtime-pcb[i].intime;
pcb[i].turnnumber=(float)pcb[i].turntime/pcb[i].needtime;
i++;
if(i==n){
i=0;
}
if(pcb[i].state=='F'){
j++;
}
}
Print();
}while(j<n);
Print1();
}
六、实验结果截图:
图1、输入进程的效果图
图2、先来先服务算法效果图
图3、短作业优先 (SJF) 调度算法效果图
图4、响应比高者优先(HRRN)调度算法效果图
图5.1、时间片轮转(RR)调度算法效果图
图5.2、时间片轮转(RR)调度算法效果图
图5.3、时间片轮转(RR)调度算法效果图
七、试验总结:
通过几次的模拟进程的调度,对进程在操作系统中调度就更加了解,认识更深刻。