多级队列调度算法

操作系统实验导航
实验一:银行家算法 https://blog.csdn.net/weixin_46291251/article/details/115384510
实验二:多级队列调度和多级反馈队列调度算法 https://blog.csdn.net/weixin_46291251/article/details/115530582
实验三:动态分区式内存管理 https://blog.csdn.net/weixin_46291251/article/details/115772341
实验四:Linux下多进程通信 https://blog.csdn.net/weixin_46291251/article/details/116274665
实验五:进程通信的三种方式 https://blog.csdn.net/weixin_46291251/article/details/116301250
实验六:Linux文件系统实验 https://blog.csdn.net/weixin_46291251/article/details/116423798
实验七:自制简单U盘引导程序 https://blog.csdn.net/weixin_46291251/article/details/116427629
实验八:磁盘调度算法 https://blog.csdn.net/weixin_46291251/article/details/116431907
实验九:请求分页系统中的置换算法 https://blog.csdn.net/weixin_46291251/article/details/116443021
学习笔记:操作系统复习笔记 https://blog.csdn.net/weixin_46291251/article/details/117086851

  • 多级队列:该算法将系统中的进程就绪队列从一个拆分为若干个,将不同类型或性质的进程固定分配在不同的就绪队列,不同的就绪队列采用不同的调度算法,一个就绪队列中的进程可以设置不同的优先级,不同的就绪队列本身也可以设置不同的优先级。
    多级队列调度算法由于设置多个就绪队列,因此对每个就绪队列就可以实施不同的调度算法,因此,系统针对不同用户进程的需求,很容易提供多种调度策略。

题目描述:

  • 设RQ分为RQ1和RQ2
  • RQ1采用轮转法,时间片q=7.
  • RQ1>RQ2
  • RQ2采用短进程优先调度算法。
  • 测试数据如下:
  • 其中:RQ1: P1-P5,   RQ2: P6-P10 
    
进程 P1 P2 P3 P4 P5 P6 P7 P8 P9 P10
运行时间 16 11 14 13 15 21 18 10 7 14
已等待时间 6 5 4 3 2 1 2 3 4 5

程序功能

  • 对于给定的数据使用多级队列调度算法进行分析计算周转时间。其中多级队列分为RQ1和RQ2 ,RQ1采用的是时间片长度为7的时间片轮转算法,RQ2采用的是短进程优先算法。并且RQ1的优先级高于RQ2(即只有在RQ1内所有程序运行结束,RQ2才能开始运行)

设计思路

  • 时间片轮转:首先对RQ1按照等待时间长短排序,然后从头设置循环,只要队列不空就一直进行下去,每次取队头RQ1的下一个元素(RQ1仅用作标志,不存储数据)判断need是否小于等于时间片大小,小于等于则置为0后踢出队列进入finish队列,大于则将need减去时间片大小,然后将其移动至队尾。
  • 短进程优先:开始前需要对RQ2按照剩余执行时间大小进行排序,与时间片轮转法类似,不同的是这里一旦开始执行就直接执行完毕,然后下一个进程上处理机运行。

数据结构

  • 本程序每个进程用一个PCB表示,每个PCB内含有name(标识符)、need(当前仍然需要多长时间才能运行结束)、turn(周转时间(等于等待时间+运行时间))、next指针(指向等待队列的下一个进程)。两个队列的头节点分别为RQ1、RQ2还有一个结束队列Finish(运行结束后进程从原队列进入这里)
typedef struct tag_pcb {char name[8];int need = 0;//需要运行的时间int turn = 0;//周转时间=等待时间+运行时间struct tag_pcb* next = NULL;
}PCB;
PCB* RQ1=new PCB, * RQ2 = new PCB, * Finish = new PCB;

代码实现:

#include<iostream>
#include <fstream>
using namespace std;typedef struct tag_pcb {char name[8];int need = 0;//需要运行的时间int turn = 0;//周转时间=等待时间+运行时间struct tag_pcb* next = NULL;
}PCB;
PCB* RQ1=new PCB, * RQ2 = new PCB, * Finish = new PCB;
const int TimePiece = 7;//时间片长度void ReadFile(){ifstream In("RQ1.txt");PCB* Current = RQ1;while (!In.eof()) {PCB* Cur = new PCB;In >> Cur->name >> Cur->need>> Cur->turn;Current->next = Cur;Current = Current->next;}In.close();ifstream In1("RQ2.txt");PCB* Current1 = RQ2;while (!In1.eof()) {PCB* Cur1 = new PCB;In1 >> Cur1->name >> Cur1->need >> Cur1->turn;Current1->next = Cur1;Current1 = Current1->next;}In1.close();
}void Q1_Insert(PCB a) { //时间片轮转算法队列的插入(插入尾部)PCB* Current = RQ1;while (Current->next != NULL)Current = Current->next;Current->next = new PCB;*Current->next = a;//Current->next = &a;Current->next->next = NULL;}
void Q2_Insert(PCB b) { //短进程优先调度算法队列的插入PCB* Current = RQ2;while (Current->next != NULL)Current = Current->next;Current->next = new PCB;*Current->next = b;Current->next->next = NULL;}
void Fin_Insert(PCB c) { //短进程优先调度算法队列的插入PCB* cc = new PCB;*cc = c;cc->next = Finish->next;Finish->next = cc;
}
void Q2_sort(PCB *T) {PCB* X = new PCB;//用来保存排序后的链表PCB* p = new PCB;//用来保存当此最小值的前一位PCB* Current = T->next;PCB * PreCurrent = T;PCB* TailX = X;while (T->next != NULL) {int tem = 999999;Current = T->next;PreCurrent = T;while (Current != NULL) {if (Current->need < tem) {tem = Current->need;p = PreCurrent;//cout << "处理" << p->name << p->need << "\n";}Current = Current->next;PreCurrent = PreCurrent->next;}TailX->next = p->next;TailX = TailX->next;if (p->next->next != NULL)p->next = p->next->next;elsep->next = NULL;      }*T = *X;
}int main()
{ReadFile();int clock = 0; //时钟while (RQ1->next != NULL) {//表示RQ1还有元素int t = TimePiece;PCB* Current = RQ1->next;int fin = 0;if (Current->need <= t)t = Current->need, fin = 1;clock += t;//表示pi运行t//输出计算过程//cout << "\n" << Current->name << "_____" << Current->turn << "__+ ___" << clock << "__= ___" << Current->turn +clock << "\n";Current->need -= t;if (fin)Current->turn += clock, Fin_Insert(*Current);//运行结束    elseQ1_Insert(*Current);//进入队尾等待运行if (Current->next == NULL)break;RQ1->next = Current->next;}clock = 0;//时钟要清空一次Q2_sort(RQ2);//先排序cout << "RQ2:__"; for (PCB* Current2 = RQ2->next; Current2 != NULL; Current2 = Current2->next)cout << Current2->name << "--";while (RQ2->next != NULL) {//表示RQ2还有元素(到这一步默认RQ1已经为空)PCB* Current3 = RQ2->next;int t = Current3->need;clock += t;//表示pi运行tCurrent3->need -= t;//实质为清空Current3->turn += clock;Fin_Insert(*Current3);if (Current3->next == NULL)break;RQ2->next = Current3->next;}int SUM = 0;for (PCB* Current2 = Finish->next; Current2 != NULL; Current2 = Current2->next) {cout << "\n" << Current2->name <<"\t"<< Current2->turn ;SUM += Current2->turn;}cout << "\n总周转时间为:" << SUM << "\n";
}
  • 多级队列调度测试结果:

附:

多级反馈队列调度算法如下原理:

  • 1、设有N个队列(Q1,Q2…QN),其中各个队列对于处理机的优先级是不一样的,也就是说位于各个队列中的作业(进程)的优先级也是不一样的。一般来说,优先级Priority(Q1) > Priority(Q2) > … > Priority(QN)。怎么讲,位于Q1中的任何一个作业(进程)都要比Q2中的任何一个作业(进程)相对于CPU的优先级要高(也就是说,Q1中的作业一定要比Q2中的作业先被处理机调度),依次类推其它的队列。
  • 2、对于优先级最低的队列来说,里面是遵循时间片轮转法。也就是说,位于队列QN中有M个作业,它们的运行时间是通过QN这个队列所设定的时间片来确定的;对于其他队列,遵循的是先来先服务算法,每一进程分配一定的时间片,若时间片运行完时进程未结束,则进入下一优先级队列的末尾。
  • 3、各个队列的时间片是一样的吗?
    不一样,这就是该算法设计的精妙之处。各个队列的时间片是随着优先级的增加而减少的,也就是说,优先级越高的队列中它的时间片就越短。同时,为了便于那些超大作业的完成,最后一个队列QN(优先级最低的队列)的时间片一般很大(不需要考虑这个问题)。

上述程序在某一进程在一级队列运行一轮后没有运行完毕,若加入二级队列而不是加入原队列的尾部,则可以实现简单的多级反馈队列调度算法
两种算法的不同之处就在于:当一个RQ1中的进程在时间片结束之后是回到当前的队尾还是到RQ2队列之中。
在上述程序中也很容易实现:

     if (fin)Current->turn += clock, Fin_Insert(*Current);//运行结束    elseQ1_Insert(*Current);//进入队尾等待运行

修改为:

     if (fin)Fin_Insert(*Current);//运行结束    elseQ2_Insert(*Current);//进入二级队列等待运行Current->turn += clock,

上述两种代码分别实现了上述两种功能,执行时只需选一种在相应位置即可。

  • 多级反馈队列调度测试结果:

由分析上述数据容易发现:在该测试数据的情况下多级反馈队列调度算法是要优于多级队列调度的

多级队列调度和多级反馈队列调度算法的实现相关推荐

  1. 操作系统:Java模拟CPU调度算法(非抢占短进程优先、可抢占优先权调度、多级反馈队列调度)

    本人是个普通学生,写下博客用于自我复习.自我总结. 本人编写算法水平不高,仅供各位参考. 首先,先简述一下各个算法的定义.因为我个人在查阅算法相关信息时,发现这些算法在某种程度上来说,可能会存在一些歧 ...

  2. linux多级反馈队列的实现,多级反馈队列调度算法的实现

    <多级反馈队列调度算法的实现>由会员分享,可在线阅读,更多相关<多级反馈队列调度算法的实现(16页珍藏版)>请在人人文库网上搜索. 1.学生实习报告课程名称_ 数据结构与数据处 ...

  3. linux多级反馈队列的实现,多级反馈队列调度算法详解

    通常在使用多级队列调度算法时,进程进入系统时被永久地分配到某个队列.例如,如果前台和后台进程分别具有单独队列,那么进程并不从一个队列移到另一个队列,这是因为进程不会改变前台或后台的性质.这种设置的优点 ...

  4. java多级反馈队列进程调度,多级队列反馈调度算法 请教多级反馈队列调度算法...

    请教多级反馈队列调度算法???????????? 在某一操作系统中对进程调度采用多级反馈队列调度算法.现设定采用三级分数给小编了,小编来 0时刻A到达,进入I队列,执行2个时间段后,转向队列II,再执 ...

  5. 多级反馈队列调度算法(转)

    多级反馈队列调度算法 如果有很多任务排队等着被处理,哪个任务先被处理,哪个任务后处理,这个需要由操作系统决定,这就是调度.多级反馈队列调度算法是目前操作系统调度算法中被公认的一种较好的调度算法.它可以 ...

  6. java模拟实现操作系统进程调度中的多级反馈队列算法

    java模拟实现操作系统进程调度中的多级反馈队列算法 操作系统学了一学期了,期末作业布置下来,用编程语言模拟进程调度的过程,只会java,于是就写了一下,通过控制台模拟,模拟过程看起来可能十分不直观. ...

  7. 多级队列调度算法可视化界面_操作系统:多级反馈队列调度算法模拟(Java实现)...

    package com.algorithm.multiStageFeedback; import java.util.*; /** * @Class MSFQS * @Description 多级反馈 ...

  8. 进程调度之多级反馈队列调度算法和多级调度算法区别

     多级反馈队列调度算法和多级调度算法区别 多级调度算法减去了多级反馈队列算法的调度功能: 在多级调度算法中,系统中会将进程进行优先级分类,比如优先级分类(A,B,C,D) 优先级A>B>C ...

  9. 多级队列调度算法可视化界面_C++实现操作系统调度算法(FSFS,SJF,RR,多级反馈队列算法)...

    #include #include #include #include using namespace std; unsigned int q_id=0; //用于队列进程号的全局变量 unsigne ...

最新文章

  1. transformers库的使用【二】tokenizer的使用,模型的保存自定义
  2. TL-ER5120路由器配置文档
  3. 计组之总线:2、总线仲裁(链式查询、计数器查询、独立请求、分布式查询)
  4. 使用app-inspector时报错connect ECONNREFUSED 127.0.0.1:8001的解决方案
  5. php 5.4 5.2区别,PHP5.5.2和php5.4.18发布
  6. HALCON 21.11:深度学习笔记---分类(10)
  7. hadoop yarn如何启动聚合日志
  8. 网页下载CAB文件总结
  9. 基本操作?这46个 Linux 面试常见问题送给你
  10. Cubase Elements v11.0.0 WiN 23GB含音色库 中文完整版编曲录音软件
  11. [华为] 华为交换机接口配置报错指南
  12. 关于IBM刀片服务器
  13. 腾讯笔试题:纸牌游戏
  14. 基于微信小程序的毕业设计题目(36)PHP电影院售票小程序(含开题报告、任务书、中期报告、答辩PPT、论文模板)
  15. java adobe ocr_Acrobat自带的OCR识别文本功能提取图片文字
  16. 二十一世纪大学英语读写教程(第三册)学习笔记(原文)——10 - Plain Talk About Handling Stress(浅谈如何缓解压力)
  17. NOIP2014 Day1T1生活大爆炸版石头剪刀布 模拟
  18. 9.NodeJs仿Express封装
  19. java能做什么(java能做什么项目)
  20. shell判断给定日期是否是周末or月末

热门文章

  1. 爱上经典之罗大佑《鹿港小镇》
  2. 生活片段(5)我所见过的母亲4
  3. 接口文档如何编写,接口文档快速生成工具
  4. linux过滤包大小命令,每天学习一个命令:zgrep 不解压过滤压缩包中文本
  5. Python 为什么要有 pass 语句?收藏防迷路
  6. 向大牛学习!11名顶尖设计师的设计启迪+职业忠告
  7. android 虚拟机访问外网的方法
  8. 为Solaris服务器配置款安全的防火墙
  9. Police Recruits
  10. 老司机总结的21条即学即用经验