操作系统:实验一 进程调度算法
实验一 进程调度算法
一、实验目的
用高级语言编写和调试一个进程调度程序,以加深对进程的概念及进程调度算法的理解.
二、实验指导
设计一个有 N个进程共行的进程调度程序。
进程调度算法:分别采用先来先服务算法、短作业优先算法、高响应比优先算法实现。
每个进程用一个进程控制块( PCB)表示。进程控制块可以包含如下信息:进程名、优先级、到达时间、要求服务时间、进程状态等等。 其中到达时间和要求服务时间可以在程序中进行初始化或者在程序开始时由键盘输入。
每个进程的状态可以是就绪 W(Wait)、运行R(Run)、或完成F(Finish)三种状态之一。
每个进程完成后要打印该作业的开始运行时刻、完成时刻、周转时间和带权周转时间,这一组进程完成后要计算并打印这组进程的平均周转时间、带权平均周转时间。
算法的流程图如图1-1
三、提示
1、在采用短作业优先算法和高响应比优先算法进行调度时应注意进程的到达时间,对于没有到达的进程不应参与调度。
2、注意在采用高响应比优先算法时计算优先权的时机,因为采用动态优先权,所以应在每次调度之前都重新计算优先权,高响应比优先算法采用下列公式计算优先权
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;elsepcb[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;elsepcb[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;elsepcb[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;//当前时间,初始化为0sort(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;elsepcb[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;//占用cpucout<<"\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;elsepcb[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;//占用cpucout<<"\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;elsepcb[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;//占用cpucout<<"\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;
}
运行效果:
操作系统:实验一 进程调度算法相关推荐
- 操作系统实验二——进程调度算法(FCFS、RR)
目录 进程调度算法 FCFS算法代码 RR算法代码 进程调度算法 FCFS算法代码 #include <stdio.h> #include <string.h> #includ ...
- 操作系统实验四 进程运行轨迹的跟踪与统计(哈工大李治军)
实验4 进程运行轨迹的跟踪与统计 实验目的 掌握 Linux 下的多进程编程技术: 通过对进程运行轨迹的跟踪来形象化进程的概念: 在进程运行轨迹跟踪的基础上进行相应的数据统计,从而能对进程调度算法进行 ...
- 操作系统实验二(调度算法模拟-先进先出-时间片轮转法-优先服务调度算法)
实验二 进程调度 一. 实验目的 1. 理解进程运行的并发性. 2. 理解处理器的三级调度. 3. 掌握先来先服务的进程调度算法. 4. 掌握短 ...
- 操作系统——实验贰——进程通信(一)管道及共享内存
一. 实验目的 熟悉并掌握管道机制,并实现进程间通信 熟悉并掌握共享内存机制,并实现进程间通信 二. 实验内容 任务一: (1)阅读以上父子进程利用管道进行通信的例子(例1),写出程序的运行结果并分析 ...
- 2020 操作系统 实验二 进程通信
实验二.进程通信 一.实验名称 进程通信 二.实验目的 掌握用邮箱方式进行进程通信的方法,并通过设计实现简单邮箱理解进程通信中的同步问题以及解决该问题的方法. 三.实验原理 邮箱机制类似于日常使用的信 ...
- 操作系统实验·Linux进程通信与内存管理
预备知识 Linux进程的数据结构 在Linux中,进程用task_struct表示,所有进程被组织到以init_task为表头的双向链表中(见[include/linux/sched.h]SET_L ...
- 操作系统——实验二 进程管理
1.实验目的 (1)加深对进程概念的理解,明确进程和程序的区别. (2)进一步认识并发执行的实质. (3)分析进程竞争资源现象,学习解决进程互斥的方法. 2.实验预备内容 (1)阅读Linux的sch ...
- 操作系统实验七 磁盘调度算法的模拟与实现(C语言)
实验七 磁盘调度算法的模拟与实现 1 .实验目的 (1) 了解磁盘结构以及磁盘上数据的组织方式. (2) 掌握磁盘访问时间的计算方式. (3) 掌握常用磁盘调度算法及其相关特性. 2 .实验基本知识及 ...
- 操作系统实验二——时间片轮转调度算法(RR算法)(新进程放队首和队尾两种C++实现)
情况介绍 基本原理 系统将所有就绪进程按照FCFS的原则,排成一个队列依次调度. 把CPU分配给队首进程,执行一个时间片(10-100ms). 时间片用完后,系统计时器发出时钟中断,该进程将被剥夺CP ...
最新文章
- c51矩形波输出汇编语言,51单片机汇编语言编程:用定时器控制输出矩形波
- Android开发之Dialog的三种列表显示(解读谷歌官方API)
- Kafka、ActiveMQ、RabbitMQ、RocketMQ 区别以及高可用原理
- android 之 Hnadler 、Message 、Looper
- .net 刷新页面防止表单二次提交
- 使用 python 的 urllib2和 urllib模块爆破 form 表单的简易脚本
- UITextView
- Java基础——Ajax(一)
- Visual Studio 中常用的快捷键
- WPF管理系统自定义分页控件 - WPF特工队内部资料
- android 免root自动滑动,无需root自动点击屏幕软件
- UML基础(八)--构件图
- 安鸾渗透实战平台--综合渗透--企业网站渗透流程
- 基于单片机控制的程控有源滤波器电路
- 解决echarts缩放模糊问题
- PAT乙级-1055 集体照 (25分)
- python安装PIL模块
- 互融云人行二代征信系统对接服务
- html黑科技导入res,css黑科技
- Swing之绘图消除锯齿
热门文章
- 提供一个vs6,vs2005,vs2008,office2007可以下载的地址.
- 整理 node-sass 安装失败的原因及解决办法
- 【Vue.js】Vue 学习笔记
- Ormlite的工具使用
- 【观察】数字中国的新机遇,神州数码的新角色
- 重点客户销售数据分析python_项目实战 | 使用python分析销售数据
- reload php-fpm命令,php-fpm的reload过程
- 30.7.1 通过mysqladmin修改用户密码
- matlab kml批量转为shp文件,arcpy实现 kml批量转出为shp
- Mac Pro 8g java 开发_2017款MacBook Pro开发java,8g内存够用吗?