实验一 进程调度算法

一、实验目的

  用高级语言编写和调试一个进程调度程序,以加深对进程的概念及进程调度算法的理解.

二、实验指导

设计一个有 N个进程共行的进程调度程序。

  进程调度算法:分别采用先来先服务算法、短作业优先算法、高响应比优先算法实现。

  每个进程用一个进程控制块( PCB)表示。进程控制块可以包含如下信息:进程名、优先级、到达时间、要求服务时间、进程状态等等。 其中到达时间和要求服务时间可以在程序中进行初始化或者在程序开始时由键盘输入。

  每个进程的状态可以是就绪 W(Wait)、运行R(Run)、或完成F(Finish)三种状态之一。

  每个进程完成后要打印该作业的开始运行时刻、完成时刻、周转时间和带权周转时间,这一组进程完成后要计算并打印这组进程的平均周转时间、带权平均周转时间。

   算法的流程图如图1-1

三、提示

1、在采用短作业优先算法和高响应比优先算法进行调度时应注意进程的到达时间,对于没有到达的进程不应参与调度。

2、注意在采用高响应比优先算法时计算优先权的时机,因为采用动态优先权,所以应在每次调度之前都重新计算优先权,高响应比优先算法采用下列公式计算优先权

操作系统:实验一   进程调度算法_进程调度


操作系统:实验一   进程调度算法_进程调度_02


fcfs算法:

int cmp(PCB a,PCB b)//fcfs
{
return a.arrive<b.arrive;
}
sort(pcb,pcb+5,cmp);
for(int i=0; i<5; i++)
{
if(pcb[i].arrive>finish)
pcb[i].end = pcb[i].arrive+pcb[i].service;
else
pcb[i].end = pcb[i].service+finish;
finish = pcb[i].end;
pcb[i].turnover = pcb[i].end-pcb[i].arrive;//周转时间=完成时间-到达时间
pcb[i].start = pcb[i].end-pcb[i].service;
pcb[i].author_turnover = double(pcb[i].turnover)/pcb[i].service;//带权周转时间=周转时间/服务时间
sum_turnover+=pcb[i].turnover;
sum_author_turnover+=pcb[i].author_turnover;
fcfs.push_back(pcb[i]);
}

sjf算法:

int cmp(PCB a,PCB b)//fcfs
{
return a.arrive<b.arrive;
}
int cmp1(PCB a,PCB b)//sjf 排序,按service升序排序,如果service相等,则按arrive升序排序
{
return (a.service<b.service)||(a.service==b.service&&a.arrive<b.arrive);
}
sort(pcb,pcb+5,cmp);//排序
for(int i=0; i<5; i++)
{
while(j<5&&pcb[j].arrive<=finish)//当有新的进程的进入时间小于当前时间,就加入就绪队列
j++;
sort(pcb+i,pcb+j,cmp1);
if(pcb[i].arrive>finish)
pcb[i].end = pcb[i].arrive+pcb[i].service;
else
pcb[i].end = pcb[i].service+finish;
finish = pcb[i].end;
pcb[i].turnover = pcb[i].end-pcb[i].arrive;//周转时间=完成时间-到达时间
pcb[i].start = pcb[i].end-pcb[i].service;
pcb[i].author_turnover = double(pcb[i].turnover)/pcb[i].service;//带权周转时间=周转时间/服务时间
sum_turnover+=pcb[i].turnover;
sum_author_turnover+=pcb[i].author_turnover;
sjf.push_back(pcb[i]);
}

hrrn算法:

int cmp(PCB a,PCB b)//fcfs
{
return a.arrive<b.arrive;
}
int cmp2(PCB p1, PCB p2) //hrrn
{
return (p1.priority > p2.priority) || (p1.priority==p2.priority && p1.arrive<p2.arrive);
}
sort(pcb, pcb+5, cmp);
for(int i = 0; i < 5; i++)
{
while(j<5 && pcb[j].arrive <= finish)
j++;
for(int k = i; k < j; k++)
pcb[k].priority = (finish-pcb[k].arrive+pcb[k].service) / pcb[k].service;
sort(pcb+i, pcb+j, cmp2);

if(pcb[i].arrive > finish)
pcb[i].end = pcb[i].arrive + pcb[i].service;
else
pcb[i].end = finish + pcb[i].service;
pcb[i].turnover = pcb[i].end - pcb[i].arrive;
finish = pcb[i].end;
pcb[i].start = pcb[i].end-pcb[i].service;
pcb[i].author_turnover = double(pcb[i].turnover)/pcb[i].service;//带权周转时间=周转时间/服务时间
sum_turnover+=pcb[i].turnover;
sum_author_turnover+=pcb[i].author_turnover;
hrrn.push_back(pcb[i]);
}

源代码:

#include<bits/stdc++.h>
#include<windows.h>
using namespace std;
struct PCB
{
int pid;//进程号
char pname;//进程名
double priority;//优先级
int arrive;//到达时间
int service;//服务时间
int start;//开始时间
int end;//结束时间
int turnover;//周转时间
double author_turnover;//带权周转时间
} pcb[5];

double fcfs_author,fcfs_turnover,sjf_author,sjf_turnover,hrrn_author,hrrn_turnover;
vector<PCB> fcfs;
vector<PCB> sjf;
vector<PCB> hrrn;

int cmp(PCB a,PCB b)//fcfs
{
return a.arrive<b.arrive;
}

int cmp1(PCB a,PCB b)//sjf 排序,按service升序排序,如果service相等,则按arrive升序排序
{
return (a.service<b.service)||(a.service==b.service&&a.arrive<b.arrive);
}

int cmp2(PCB p1, PCB p2) //hrrn
{
return (p1.priority > p2.priority) || (p1.priority==p2.priority && p1.arrive<p2.arrive);
}

void Compare()//打印算法对比
{
cout<<"先来先服务调度算法!"<<endl;
cout<<"\t进程名\t\t"<<"到达时间\t"<<"服务时间\t"<<"完成时间\t"<<"周转时间\t"<<"带权周转"<<endl;
for(int i=0;i<fcfs.size();i++)
{
cout<<"\t"<<fcfs[i].pname<<"\t\t"<<fcfs[i].arrive<<"\t\t"<<fcfs[i].service<<"\t\t"<<fcfs[i].end<<"\t\t"<<fcfs[i].turnover<<"\t\t";
printf("%.2lf\n",fcfs[i].author_turnover);
}
printf("\t平均周转时间:%.2lf\t",fcfs_turnover);
printf("\t平均带权周转时间:%.2lf\n",fcfs_author);

cout<<endl;
cout<<endl;

cout<<"短作业优先算法!"<<endl;
cout<<"\t进程名\t\t"<<"到达时间\t"<<"服务时间\t"<<"完成时间\t"<<"周转时间\t"<<"带权周转"<<endl;
for(int i=0;i<sjf.size();i++)
{
cout<<"\t"<<sjf[i].pname<<"\t\t"<<sjf[i].arrive<<"\t\t"<<sjf[i].service<<"\t\t"<<sjf[i].end<<"\t\t"<<sjf[i].turnover<<"\t\t";
printf("%.2lf\n",sjf[i].author_turnover);
}
printf("\t平均周转时间:%.2lf\t",sjf_turnover);
printf("\t平均带权周转时间:%.2lf\n",sjf_author);

cout<<endl;
cout<<endl;

cout<<"高响应比优先算法!"<<endl;
cout<<"\t进程名\t\t"<<"到达时间\t"<<"服务时间\t"<<"完成时间\t"<<"周转时间\t"<<"带权周转"<<endl;
for(int i=0;i<hrrn.size();i++)
{
cout<<"\t"<<hrrn[i].pname<<"\t\t"<<hrrn[i].arrive<<"\t\t"<<hrrn[i].service<<"\t\t"<<hrrn[i].end<<"\t\t"<<hrrn[i].turnover<<"\t\t";
printf("%.2lf\n",hrrn[i].author_turnover);
}
printf("\t平均周转时间:%.2lf\t",hrrn_turnover);
printf("\t平均带权周转时间:%.2lf\n",hrrn_author);
system("pause");
system("cls");
}

void print()
{
system("cls");
cout<<"\n\n";
cout<<"\t 进程名:";
for(int i=0; i<5; i++)
{
cout<<"\t"<<pcb[i].pname;
}
cout<<endl;
cout<<"\t到达时间:";
for(int i=0; i<5; i++)
{
cout<<"\t"<<pcb[i].arrive;
}
cout<<endl;
cout<<"\t服务时间:";
for(int i=0; i<5; i++)
{
cout<<"\t"<<pcb[i].service;
}
cout<<endl;
cout<<endl;
system("pause");
system("cls");
}

void FCFS() //先来先服务
{

system("cls");
cout<<"先来先服务调度算法!"<<endl;
//打印
cout<<"\n\n";
cout<<"\t 进程名:";
for(int i=0; i<5; i++)
{
cout<<"\t"<<pcb[i].pname;
}
cout<<endl;
cout<<"\t到达时间:";
for(int i=0; i<5; i++)
{
cout<<"\t"<<pcb[i].arrive;
}
cout<<endl;
cout<<"\t服务时间:";
for(int i=0; i<5; i++)
{
cout<<"\t"<<pcb[i].service;
}
cout<<endl;
cout<<endl;
int finish = 0;//当前时间,初始化为0
sort(pcb,pcb+5,cmp);
int sum_turnover = 0;
double sum_author_turnover = 0.0;
for(int i=0; i<5; i++)
{
if(pcb[i].arrive>finish)
pcb[i].end = pcb[i].arrive+pcb[i].service;
else
pcb[i].end = pcb[i].service+finish;
finish = pcb[i].end;
pcb[i].turnover = pcb[i].end-pcb[i].arrive;//周转时间=完成时间-到达时间
pcb[i].start = pcb[i].end-pcb[i].service;
pcb[i].author_turnover = double(pcb[i].turnover)/pcb[i].service;//带权周转时间=周转时间/服务时间
sum_turnover+=pcb[i].turnover;
sum_author_turnover+=pcb[i].author_turnover;
fcfs.push_back(pcb[i]);
}

//过程
int cpu = 0;
int f[5] = {0};//初始化为0,代表不占用
while(1)
{
if(cpu==pcb[4].end)
{
cout<<"\t"<<pcb[4].end<<" "<<"进程"<<pcb[4].pname<<"结束\n"<<endl;
break;
}
for(int i=0; i<5; i++)
{
if(pcb[i].arrive==cpu)
{
cout<<"\t"<<cpu<<" "<<"进程"<<pcb[i].pname<<"到达内存\n"<<endl;
}
}
for(int i=0; i<5; i++)
{
if((pcb[i].start==cpu&&i==0)||(pcb[i].start==cpu&&f[i-1]==0))
{
f[i]=1;//占用cpu
cout<<"\t"<<cpu<<" "<<"进程"<<pcb[i].pname<<"开始执行\n"<<endl;
Sleep(pcb[i].service*100);
}
if(pcb[i].end==cpu)
{
cout<<"\t"<<cpu<<" "<<"进程"<<pcb[i].pname<<"结束\n"<<endl;
f[i]=0;//解除占用cpu
}
}
cpu++;
}

//计算
double avg_turnover = (double)sum_turnover/5;
double avg_author_turnover = (double)sum_author_turnover/5;
cout<<"\t进程名\t\t"<<"到达时间\t"<<"服务时间\t"<<"完成时间\t"<<"周转时间\t"<<"带权周转"<<endl;
for(int i=0; i<5; i++)
{
cout<<"\t"<<pcb[i].pname<<"\t\t"<<pcb[i].arrive<<"\t\t"<<pcb[i].service<<"\t\t"<<pcb[i].end<<"\t\t"<<pcb[i].turnover<<"\t\t";
printf("%.2lf\n",pcb[i].author_turnover);
}
printf("\t平均周转时间:%.2lf\t",avg_turnover);
fcfs_turnover=avg_turnover;
printf("\t平均带权周转时间:%.2lf\n",avg_author_turnover);
fcfs_author=avg_author_turnover;
system("pause");
system("cls");
}



void SJF()
{
system("cls");
cout<<"短作业优先调度算法!"<<endl;
//打印
cout<<"\n\n";
cout<<"\t 进程名:";
for(int i=0; i<5; i++)
{
cout<<"\t"<<pcb[i].pname;
}
cout<<endl;
cout<<"\t到达时间:";
for(int i=0; i<5; i++)
{
cout<<"\t"<<pcb[i].arrive;
}
cout<<endl;
cout<<"\t服务时间:";
for(int i=0; i<5; i++)
{
cout<<"\t"<<pcb[i].service;
}
cout<<endl;
cout<<endl;

int i,j=0,finish=0;//j为当前就绪队列的末尾指针
sort(pcb,pcb+5,cmp);//排序

// for(int i=0;i<5;i++)
// cout<<pcb[i].pname; 测试排序是否正确
int sum_turnover = 0;
double sum_author_turnover = 0.0;
for(int i=0; i<5; i++)
{
while(j<5&&pcb[j].arrive<=finish)//当有新的进程的进入时间小于当前时间,就加入就绪队列
j++;
sort(pcb+i,pcb+j,cmp1);
if(pcb[i].arrive>finish)
pcb[i].end = pcb[i].arrive+pcb[i].service;
else
pcb[i].end = pcb[i].service+finish;
finish = pcb[i].end;
pcb[i].turnover = pcb[i].end-pcb[i].arrive;//周转时间=完成时间-到达时间
pcb[i].start = pcb[i].end-pcb[i].service;
pcb[i].author_turnover = double(pcb[i].turnover)/pcb[i].service;//带权周转时间=周转时间/服务时间
sum_turnover+=pcb[i].turnover;
sum_author_turnover+=pcb[i].author_turnover;
sjf.push_back(pcb[i]);
}

//过程
int cpu = 0;
int f[5] = {0};//初始化为0,代表不占用
while(1)
{
if(cpu==pcb[4].end)
{
cout<<"\t"<<pcb[4].end<<" "<<"进程"<<pcb[4].pname<<"结束\n"<<endl;
break;
}
for(int i=0; i<5; i++)
{
if(pcb[i].arrive==cpu)
{
cout<<"\t"<<cpu<<" "<<"进程"<<pcb[i].pname<<"到达内存\n"<<endl;
}
}
for(int i=0; i<5; i++)
{
if((pcb[i].start==cpu&&i==0)||(pcb[i].start==cpu&&f[i-1]==0))
{
f[i]=1;//占用cpu
cout<<"\t"<<cpu<<" "<<"进程"<<pcb[i].pname<<"开始执行\n"<<endl;
Sleep(pcb[i].service*100);
}
if(pcb[i].end==cpu)
{
cout<<"\t"<<cpu<<" "<<"进程"<<pcb[i].pname<<"结束\n"<<endl;
f[i]=0;//解除占用cpu
}
}
cpu++;
}


//计算
double avg_turnover = (double)sum_turnover/5;
double avg_author_turnover = (double)sum_author_turnover/5;
cout<<"\t进程名\t\t"<<"到达时间\t"<<"服务时间\t"<<"完成时间\t"<<"周转时间\t"<<"带权周转"<<endl;
for(int i=0; i<5; i++)
{
cout<<"\t"<<pcb[i].pname<<"\t\t"<<pcb[i].arrive<<"\t\t"<<pcb[i].service<<"\t\t"<<pcb[i].end<<"\t\t"<<pcb[i].turnover<<"\t\t";
printf("%.2lf\n",pcb[i].author_turnover);
}
printf("\t平均周转时间:%.2lf\t",avg_turnover);
sjf_turnover=avg_turnover;
printf("\t平均带权周转时间:%.2lf\n",avg_author_turnover);
sjf_author=avg_author_turnover;
system("pause");
system("cls");
}

void init()
{
cout<<endl;
// for(int i=0;i<5;i++)
// {
// pcb[i].pid = i;
// cout<<"进程:"<<i<<endl;
// cout<<"进程名:";
// cin>>pcb[i].pname;
// cout<<"到达时间:";
// cin>>pcb[i].arrive;
// cout<<"服务时间:";
// cin>>pcb[i].service;
// cout<<endl;
// }
pcb[0].pname='A';
pcb[0].arrive=0;
pcb[0].service=3;

pcb[1].pname='B';
pcb[1].arrive=4;
pcb[1].service=6;

pcb[2].pname='C';
pcb[2].arrive=4;
pcb[2].service=4;

pcb[3].pname='D';
pcb[3].arrive=6;
pcb[3].service=5;

pcb[4].pname='E';
pcb[4].arrive=8;
pcb[4].service=2;
system("cls");
}

void menu()
{
cout<<endl;
cout<<endl;
cout<<"\t 进程调度模拟程序"<<endl;
cout<<endl;
cout<<"\t1. 输入作业情况"<<endl;
cout<<endl;
cout<<"\t2. 显示作业情况"<<endl;
cout<<endl;
cout<<"\t3. 先来先服务算法"<<endl;
cout<<endl;
cout<<"\t4. 短作业优先算法"<<endl;
cout<<endl;
cout<<"\t5. 高响应比优先算法"<<endl;
cout<<endl;
cout<<"\t6. 算法结果对比"<<endl;
cout<<endl;
cout<<"\t0. 退出"<<endl;
cout<<endl;
cout<<"请输入选择:";
}

void HRRN()
{
system("cls");
cout<<"高响应比调度算法!"<<endl;
//打印
cout<<"\n\n";
cout<<"\t 进程名:";
for(int i=0; i<5; i++)
{
cout<<"\t"<<pcb[i].pname;
}
cout<<endl;
cout<<"\t到达时间:";
for(int i=0; i<5; i++)
{
cout<<"\t"<<pcb[i].arrive;
}
cout<<endl;
cout<<"\t服务时间:";
for(int i=0; i<5; i++)
{
cout<<"\t"<<pcb[i].service;
}
cout<<endl;
cout<<endl;
int sum_turnover = 0;
double sum_author_turnover = 0.0;
int j=0;
int finish=0;
sort(pcb, pcb+5, cmp);
for(int i = 0; i < 5; i++)
{
while(j<5 && pcb[j].arrive <= finish)
j++;
for(int k = i; k < j; k++)
pcb[k].priority = (finish-pcb[k].arrive+pcb[k].service) / pcb[k].service;
sort(pcb+i, pcb+j, cmp2);

if(pcb[i].arrive > finish)
pcb[i].end = pcb[i].arrive + pcb[i].service;
else
pcb[i].end = finish + pcb[i].service;
pcb[i].turnover = pcb[i].end - pcb[i].arrive;
finish = pcb[i].end;
pcb[i].start = pcb[i].end-pcb[i].service;
pcb[i].author_turnover = double(pcb[i].turnover)/pcb[i].service;//带权周转时间=周转时间/服务时间
sum_turnover+=pcb[i].turnover;
sum_author_turnover+=pcb[i].author_turnover;
hrrn.push_back(pcb[i]);
}


//过程
int cpu = 0;
int f[5] = {0};//初始化为0,代表不占用
while(1)
{
if(cpu==pcb[4].end)
{
cout<<"\t"<<pcb[4].end<<" "<<"进程"<<pcb[4].pname<<"结束\n"<<endl;
break;
}
for(int i=0; i<5; i++)
{
if(pcb[i].arrive==cpu)
{
cout<<"\t"<<cpu<<" "<<"进程"<<pcb[i].pname<<"到达内存\n"<<endl;
}
}
for(int i=0; i<5; i++)
{
if((pcb[i].start==cpu&&i==0)||(pcb[i].start==cpu&&f[i-1]==0))
{
f[i]=1;//占用cpu
cout<<"\t"<<cpu<<" "<<"进程"<<pcb[i].pname<<"开始执行\n"<<endl;
Sleep(pcb[i].service*100);
}
if(pcb[i].end==cpu)
{
cout<<"\t"<<cpu<<" "<<"进程"<<pcb[i].pname<<"结束\n"<<endl;
f[i]=0;//解除占用cpu
}
}
cpu++;
}

//计算
double avg_turnover = (double)sum_turnover/5;
double avg_author_turnover = (double)sum_author_turnover/5;
cout<<"\t进程名\t\t"<<"到达时间\t"<<"服务时间\t"<<"完成时间\t"<<"周转时间\t"<<"带权周转"<<endl;
for(int i=0; i<5; i++)
{
cout<<"\t"<<pcb[i].pname<<"\t\t"<<pcb[i].arrive<<"\t\t"<<pcb[i].service<<"\t\t"<<pcb[i].end<<"\t\t"<<pcb[i].turnover<<"\t\t";
printf("%.2lf\n",pcb[i].author_turnover);
}
printf("\t平均周转时间:%.2lf\t",avg_turnover);
hrrn_turnover=avg_turnover;
printf("\t平均带权周转时间:%.2lf\n",avg_author_turnover);
hrrn_author=avg_author_turnover;
system("pause");
system("cls");
}

int main()
{
int flag=1;
while(1)
{
menu();
int sel;
cin>>sel;
switch(sel)
{
case 1:
init();
break;
case 2:
print();
break;
case 3:
FCFS();
break;
case 4:
SJF();
break;
case 5:
HRRN();
break;
case 6:
Compare();
break;
case 0:
exit(0);
}
}
return 0;
}

运行效果:

操作系统:实验一   进程调度算法_进程名_03