进程调度算法

发布时间:2024年01月20日

主要内容

一.进程调度算法

1.各调度算法思想

  1. 先来先服务算法(First Come, First Served,FCFS):这是最简单的调度算法之一。进程按照它们进入就绪队列的顺序进行调度,首先进入队列的进程首先被执行。这意味着后来的进程必须等待前面的进程完成才能执行。

  2. 短作业优先调度算法(Shortest Job First,SJF):这种算法会优先选择执行时间最短的进程。当一个新的进程进入就绪队列时,系统会比较它的执行时间与当前就绪队列中所有进程的执行时间,然后选择执行时间最短的进程来执行。

  3. 时间片轮转调度算法(Round Robin):在这种算法中,每个进程被分配一个时间片,当时间片用完时,操作系统会将该进程移到就绪队列的末尾,然后选择下一个就绪队列中的进程来执行。这种方法确保了每个进程都有机会执行,并且避免了长时间的等待。

  4. 优先级调度算法(Priority Scheduling):这种算法根据每个进程的优先级来决定执行顺序。较高优先级的进程会优先执行,而较低优先级的进程则会被推迟执行。这种算法可以是静态的(优先级在进程创建时确定)或者动态的(优先级可以随着时间变化)。
    在这里插入图片描述

这些调度算法各有优劣,适用于不同的场景和需求。选择适当的调度算法可以提高系统的性能和效率。

2.程序流程图

在这里插入图片描述

3.源代码

代码如下(示例):
#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;
}

4.运行结果分析

展示及显示作业情况
在这里插入图片描述

5.先来先服务算法

在这里插入图片描述

6.短作业优先算法

在这里插入图片描述

7.高响应优先算法

在这里插入图片描述

8.算法结果对比

在这里插入图片描述


总结

以上是今天要讲的内容,练习了进程调度算法。

文章来源:https://blog.csdn.net/weixin_59994613/article/details/135691670
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。