先来先服务算法(First Come, First Served,FCFS):这是最简单的调度算法之一。进程按照它们进入就绪队列的顺序进行调度,首先进入队列的进程首先被执行。这意味着后来的进程必须等待前面的进程完成才能执行。
短作业优先调度算法(Shortest Job First,SJF):这种算法会优先选择执行时间最短的进程。当一个新的进程进入就绪队列时,系统会比较它的执行时间与当前就绪队列中所有进程的执行时间,然后选择执行时间最短的进程来执行。
时间片轮转调度算法(Round Robin):在这种算法中,每个进程被分配一个时间片,当时间片用完时,操作系统会将该进程移到就绪队列的末尾,然后选择下一个就绪队列中的进程来执行。这种方法确保了每个进程都有机会执行,并且避免了长时间的等待。
优先级调度算法(Priority Scheduling):这种算法根据每个进程的优先级来决定执行顺序。较高优先级的进程会优先执行,而较低优先级的进程则会被推迟执行。这种算法可以是静态的(优先级在进程创建时确定)或者动态的(优先级可以随着时间变化)。
这些调度算法各有优劣,适用于不同的场景和需求。选择适当的调度算法可以提高系统的性能和效率。
#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;
}
展示及显示作业情况
以上是今天要讲的内容,练习了进程调度算法。