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

进程调度

  1.  实验目的与要求

进程调度是处理机管理的核心内容。本实验要求编程实现一个简单的进程调度程序。通过本实验可以加深理解有关进程控制块、进程队列的概念,并体会和了解进程调度算法的具体实现方法。

    2. 实验平台

操作系统:Windows

注:可使用自己熟悉的语言设计编程,但需在实验报告中注明编译环境以及编辑工具。

   3. 实验内容和要求

①设计进程控制块PCB表结构。

②输入一组进程及其相关参数。

③编制进程一个或多个调度算法,可选调度算法有:先来先服务法、短作业优先法、优先级法。

④计算出这组进程的平均周转时间。

   4.运行结果​​​​​​​

   5.运行代码

  因为每一次调度算法的时候都会把链表的节点删掉,执行一次调度算法之后,进程链表就会删掉,个人的解决办法是在创建进程链表的时候复制准备多个链表,但是这样会一定程度上造成空间浪费,各位伙伴可以尝试自己优化更好的代码。

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
typedef struct node
{
 char name;                               //进程名
 int Arrive_Time;                         //到达时间
 int Serve_Time;                          //服务时间
 int Finish_Time;                         //完成时间
 int priority;                            //优先级
 struct node *next; /*pcb define*/
}*PCB;
void ProcessCreate(PCB &head)              //创建进程函数
{
 char c;
 PCB p,q;
 head=(PCB)malloc(sizeof(node));           //申请头结点空间
 head->next=NULL;                          //刚开始头结点指向为空
 q=head;
 cout<<endl;
 while(1)
 {
 p=(PCB)malloc(sizeof(node));
 cout<<"请输入进程名称:";
 cin>>p->name;                              //输入进程名称
 cout<<"请输入"<<p->name<<"的到达时间:";
 cin>>p->Arrive_Time;                      //输入到达时间
 cout<<"请输入"<<p->name<<"的所需服务时间:";
 cin>>p->Serve_Time;                       //输入服务时间
 cout<<"请输入"<<p->name<<"的优先级:";
 cin>>p->priority;                         //输入优先级
 p->Finish_Time=0;                         //刚开始完成时间置为空
 q->next=p;                                //连接到链表末尾
 q=p;
 q->next=NULL;                             //末尾指向置空
 cin.clear();                              //清空输入缓存区
 cin.sync();
 cout<<"还有进程需要输入吗?(Y/N)";
 cin>>c;
 if(c=='n'||c=='N')                        //判断是否继续加入进程
 break;
 if(c=='y'||c=='Y'){
cin.clear();                               //清空缓冲区
cin.sync();
}
else{
system("输入错误,请重新输入");
}
 
 }
}
void Create(PCB &head_1) {
head_1=(PCB)malloc(sizeof(node));         //申请头结点空间
head_1->next=NULL;                        //刚开始头结点指向为空
}
void CopyProcess(PCB &head,PCB &head_1) { //复制相同的链表
PCB temp,p;
p=head->next;
while(p!=NULL){
temp=(PCB)malloc(sizeof(node));
temp->Arrive_Time=p->Arrive_Time;
temp->Finish_Time=p->Finish_Time;
temp->name=p->name;
temp->priority=p->priority;
temp->Serve_Time=p->Serve_Time;
temp->next=head_1->next;
head_1->next=temp;
p=p->next;
}
}
void PCB_View(PCB head)                   //查看当前所有进程信息函数
{
 PCB p;
 p=head->next;
 if(p==NULL)                              //为空则表示没有进程,都执行完了
 cout<<"当前系统中没有进程!"<<endl;
 else
 {
 cout<<endl<<"进程 到达时间 服务时间 优先级"<<endl; //表头
 while(p)
 {
 cout<<p->name<<"\t "<<p->Arrive_Time<<"\t "<<p->Serve_Time<<"\t "<<p->priority<<endl;
 p=p->next;                               //循环打印进程信息
 }
 }
}
void PCB_Sort(PCB &head)                  //将进程按到达时间从小到大排序函数
{
 PCB p,q;
 char c;
 int temp;
 p=head->next;
 q=head->next;
 while((p!=NULL)&&(p->next!=NULL))
 for(p=head->next; p->next!=NULL; p=p->next)                 //冒泡排序
 for(q=head->next; q->next!=NULL; q=q->next)                 //判断进程到达时间是否比后一个进程大
 if(q->Arrive_Time>q->next->Arrive_Time) 
 {
 c=q->name;                                                  //交换进程名字
 q->name=q->next->name;
 q->next->name=c;
 temp=q->Arrive_Time;                                        //交换到达时间
 q->Arrive_Time=q->next->Arrive_Time;
 q->next->Arrive_Time=temp;
 temp=q->Serve_Time;                                         //交换服务时间
 q->Serve_Time=q->next->Serve_Time;
 q->next->Serve_Time=temp;
 temp=q->Finish_Time;                                        //交换完成时间
 q->Finish_Time=q->next->Finish_Time;
 q->next->Finish_Time=temp;
 temp=q->priority;                                           //交换优先级
 q->priority=q->next->priority;
 q->next->priority=temp;
 }
}
int PCB_Num(PCB &head,int time)                              //找到当前时间点有多少个进程就绪了
{
 int num=0;
 PCB p;
 p=head->next;
 while(p!=NULL&&p->Arrive_Time<=time)                        //如果到达时间小于等于当前时间则表示已就绪
 {
 num++;
 p=p->next;
 }
 return num;                                                 //返回当前就绪进程个数
}
void PCB_Delet(PCB &head,PCB p)                              //将执行完的进程从链表中删除
{
 PCB q;
 q=p->next;
 p->next=q->next;                                            //指向当前进程的下一个进程
 free(q);                                                    //释放进程空间
}
void Process_FCFS(PCB &head)                                 //先来先服务算法函数
{
 PCB p,q;
 int time=0,num;
 float i=0,turn_time=0;                                      //记录总周转时间
 cout<<endl<<" 先来先服务法 "<<endl;                            
 cout<<"进程 到达时间 服务时间 优先级 完成时间 周转时间"<<endl; //表头
 p=head->next;
 while( p!=NULL)                                             //遍历所有进程
 {
 i++;                                                        //记录一共有多少个进程,好计算平均周转 
 num=PCB_Num(head,time);                                     //得到当前时间点就绪进程个数 
 if(num==0)
 time++;                                                     //如果没有进程时间继续往前走
 else
 {
 q=p->next;
 time+=p->Serve_Time;                                        //更新当前时间为:当前时间+服务时间
 p->Finish_Time=time;                                        //当前时间即为进程完成时间
 cout<<p->name<<"\t "<<p->Arrive_Time<<"\t "<<p->Serve_Time<<"\t "
<<p->priority<<"\t "<<p->Finish_Time<<"\t "<<time-p->Arrive_Time<<endl;//输出进程信息
 turn_time+=time-p->Arrive_Time;                             //把周转时间加起来
p=q;                                                         //把执行完的进程从链表删除
 }
 }
 turn_time=turn_time/num;                                    //计算平均周转时间
 cout<<"平均周转时间为:"<<turn_time<<endl;                  //输出周转时间
}
PCB Priority_max(PCB &head,int num)                          //找到就绪进程中优先级最高的进程函数
 
{
 PCB p,q,r;
 int flag=0;
 p=head->next;
 r=p;
 q=head->next;
 int max;
 max=p->priority;                                            //将最高优先级初始化为第一个进程优先级
 while(num>0)                                                //遍历就绪进程
 {
 if(p->priority<max)
 {
 max=p->priority;                                            //更新最高优先级
 r=q;                                                        //保存最高优先级进程的前一个结点 
 flag=1;                                                     //标记置 1,说明最小服务时间不为第一个结点
 
 }
 num--;
 q=p;                                                        //保存当前结点
 p=p->next;                                                  //遍历下一个结点
 }
 if(flag==0)                                                 //表示当前进程链表中第一个进程优先级最高
 r=head;
 return r;                                                   //返回最高优先级进程的前一个结点
}
void Process_Priority(PCB &head)                                //优先级法函数
{
 int time=0,num;
 float i=0,turn_time=0;                                         //记录总周转时间
 PCB p,q;
 cout<<endl<<" 优先级法 "<<endl;                                //表头
 cout<<"进程 到达时间 服务时间 优先级 完成时间 周转时间"<<endl; //表头
 while(head->next!=NULL)
 {
 i++;
 num=PCB_Num(head,time);                                       //得到当前时间点就绪进程个数
 if(num==0)
 time++;                                                       //如果没有进程时间继续往前走
 else if(num==1)
 {
 p=head->next;
 time+=p->Serve_Time;                                           //更新当前时间为:当前时间+服务时间
 p->Finish_Time=time;                                           //当前时间即为进程完成时间
 cout<<p->name<<"\t "<<p->Arrive_Time<<"\t "<<p->Serve_Time<<"\t "
<<p->priority<<"\t "<<p->Finish_Time<<"\t "<<time-p->Arrive_Time<<endl; //输出进程信息
 turn_time+=time-p->Arrive_Time;                                //把周转时间加起来
 q=head;
 PCB_Delet(head,q);                                             //把执行完的进程从链表删除
 }
 else                                                           //就绪队列中不止一个进程,需要比较目录
 {
 q=Priority_max(head,num);                                      //得到优先级高最高的进程的前驱结点
 p=q->next;
 time+=p->Serve_Time;                                           //更新当前时间为:当前时间+服务时间
 p->Finish_Time=time;                                           //当前时间即为进程完成时间
 cout<<p->name<<"\t "<<p->Arrive_Time<<"\t "<<p->Serve_Time<<"\t "
<<p->priority<<"\t "<<p->Finish_Time<<"\t "<<time-p->Arrive_Time<<endl; //输出进程信息
 turn_time+=time-p->Arrive_Time;                                //把周转时间加起来
 PCB_Delet(head,q);                                             //把执行完的进程从链表删除
 }
 }
 turn_time=turn_time/i;                                         //计算平均周转时间
 cout<<"平均周转时间为:"<<turn_time<<endl;                     //输出周转时间
}
PCB Serve_Time_min(PCB &head,int num)                           //找到就绪进程中服务时间最短的进程函数
{
 PCB p,q,t;
 int min,flag=0;
 p=head->next;
 q=head->next;
 t=head->next;
 min=p->Serve_Time;                                             //将最短服务时间初始化为第一个进程时间
 while(num>0)                                                   //遍历就绪进程
 {
 num--;
 if(p->Serve_Time<min)
 {
 min=p->Serve_Time;                                             //更新最短服务时间
 t=q;                                                           //保存最短服务时间进程的前一个结点
 flag=1;                                                        //标记置 1,说明最小服务时间不为第一个结点
 }
 q=p;                                                           //保存当前结点
 p=p->next;                                                     //遍历下一个结点
 }
 if(flag==0)                                                    //表示当前进程链表中第一个进程服务时间最短
 t=head;
 return t;                                                      //返回最短服务时间进程的前一个结点
}
void Process_SJF(PCB &head)                                     //短作业优先法的函数
{
 int time=0,num;
 float i=0,turn_time=0;                                         //记录总周转时间
 PCB p,q;
 cout<<endl<<" 短作业优先法 "<<endl;                            //表头
 cout<<"进程 到达时间 服务时间 优先级 完成时间 周转时间"<<endl; //表头
 while(head->next!=NULL)
 {
 i++;
 num=PCB_Num(head,time);                                        //得到当前时间点就绪进程个数
 if(num==0)
 time++;                                                        //如果没有进程时间继续往前走
 else if(num==1)                                                //就绪队列中只有 1 个进程
 {
 p=head->next;
 time+=p->Serve_Time;                                            //更新当前时间为:当前时间+服务时间
 p->Finish_Time=time;                                            //当前时间即为进程完成时间
 cout<<p->name<<"\t "<<p->Arrive_Time<<"\t "<<p->Serve_Time<<"\t "
<<p->priority<<"\t "<<p->Finish_Time<<"\t "<<time-p->Arrive_Time<<endl; //输出进程信息
 turn_time+=time-p->Arrive_Time;                                  //把周转时间加起来
 q=head;
 PCB_Delet(head,q);                                               //把执行完的进程从链表删除
 }
 else                                                             //就绪队列中不止一个进程,需要比较
 {
 q=Serve_Time_min(head,num);                                      //找到服务时间最短的那个进程的前驱结点
 p=q->next;
 time+=p->Serve_Time;
 p->Finish_Time=time;                                             //当前时间即为进程完成时间
 cout<<p->name<<"\t "<<p->Arrive_Time<<"\t "<<p->Serve_Time<<"\t "
<<p->priority<<"\t "<<p->Finish_Time<<"\t "<<time-p->Arrive_Time<<endl; //输出进程信息
 turn_time+=time-p->Arrive_Time;                                  //把周转时间加起来
 PCB_Delet(head,q);                                               //把执行完的进程从链表删除 
 }
 }
 turn_time=turn_time/i;                                           //计算平均周转时间
 cout<<"平均周转时间为:"<<turn_time<<endl;                       //输出周转时间
}
void menu()                                                       //菜单函数
{
 PCB head;
 PCB head_1;
 PCB head_2;
 int a;
 cout<<"*********************进程调度算法************************"<<endl;
 cout<<"*                                                       *"<<endl;
 cout<<"* 1. 创建进程                            2 查看进程信息 *"<<endl;
 cout<<"*                                                       *"<<endl;
 cout<<"*                    可选择的算法:                     *"<<endl;
 cout<<"*                                                       *"<<endl;
 cout<<"*                                                       *"<<endl;
 cout<<"* 3.先来先服务法     4.短作业优先法      5.优先级法     *"<<endl;
 cout<<"*********************************************************"<<endl;
 while(1)
 {
 cout<<endl<<"请选择要执行的功能:";
 cin>>a;
 cin.clear();
 cin.sync();
 if(a==1)
 {
 ProcessCreate(head);                                           //创建进程
 PCB_Sort(head);
 Create(head_1); 
 Create(head_2); 
 CopyProcess(head,head_1);
 PCB_Sort(head_1);
 CopyProcess(head,head_2);
 PCB_Sort(head_2);
 
 
 }
 else if(a==2)
 PCB_View(head);                                              //查看进程信息
 else if(a==3)
 Process_FCFS(head);                                          //先来先服务法
 else if(a==4)
 Process_SJF(head_1);                                         //短作业优先发 
 else if(a==5)
 Process_Priority(head_2);                                    //优先级法
 else
 {
 system("cls");                                               //输入错误清屏重新显示菜单
 menu();
 }
 }
}
int main()
{
 menu();                                                      //调用菜单
 return 0;
}

  • 10
    点赞
  • 77
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
操作系统进程调度是计算机操作系统中的一个重要部分,它负责协调和管理系统中的各个进程,以实现资源的有效利用和任务的高效执行。在C语言中进行操作系统进程调度实验,可以通过模拟不同的调度算法来理解和掌握进程调度的原理和实现过程。 首先,可以使用C语言编写一个简单的程序,模拟进程的创建、就绪、运行和结束等状态。通过定义进程控制块(PCB)、进程队列等数据结构,以及编写相应的进程管理函数,来实现对进程的管理和调度。例如,可以编写函数来创建新进程、将进程加入就绪队列、根据调度算法选择下一个要执行的进程等。 其次,可以选择不同的调度算法实验,如先来先服务(FCFS)、最短作业优先(SJF)、时间片轮转(RR)等。针对不同的调度算法,通过C语言实现相应的调度函数,并在模拟程序中进行调用,观察不同算法进程执行顺序和响应时间的影响。 最后,可以通过对进程调度实验的结果进行分析和比较,来深入理解各种调度算法的优缺点,以及在不同场景下的适用性。同时,也可以通过进一步的实验和优化,来改进模拟程序,增加更多的实际场景和特性,以更好地理解和应用操作系统进程调度的相关知识。 通过C语言进行操作系统进程调度实验,可以帮助我们更深入地理解和掌握操作系统的核心概念和原理,为今后的系统设计和开发打下坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值