一、实验目的

  1. 对进程调度的工作做进一步的理解。
  2. 了解进程调度的任务。
  3. 通过编程掌握基于优先数的时间片轮转调度算法具体实现过程。

二、实验内容

1、设计一个程序模拟实现基于优先数的时间片轮转调度算法调度处理。

2、每个进程用一个进程控制块PCB来代表,建议进程控制块的结构如下所示:

进程名

到达时间

要求运行时间

优先数

已运行时间

周转时间

指针

  • 进程名:作为进程的标识。
  • 到达时间:进程进入系统时间。
  • 要求运行时间:假设进程需要运行的单位时间数。
  • 已运行时间:假设进程已经运行的单位时间数,初值为0。
  • 状态:可假设有三种状态:未进入状态、就绪状态和结束状态。进程的初始状态都为未进入状态,到达时间-当前时间数时=0进程从未进入状态进入就绪状态;当要求运行时间-已运行时间=0时进程进入结束状态。
  • 优先数:范围0-100,优先数越小,级别越高。
  • 周转时间:进程从到达开始到结束运行所经历时间数。
  • 指针:进程按顺序排成链表(不同队列进程排列顺序不一样),用指针指出下一个进程的进程控制块首地址,最后一个进程中的指针指出第一个进程的进程控制块首地址。

3、程序开始运行时输入多个进程信息,用于实现对进程控制块的初始化。测试输入数据表1所示:

表1 输入数据表

进程名

A

B

C

D

E

F

到达时间

0

0

1

1

3

5

要求运行时间

4

5

5

4

4

4

优先数

3

2

0

10

5

2

4、程序在没有开始运行前,全部进程所处的状态都处于未进入状态。

5、程序当中应该组织三个队列:未进入队列、就绪队列和结束队列。

6、就绪队列中的就绪进程按优先数由小到大排列,优先级最高的进程,获得被调度的资格。当某一进程运行完一个时间片后,其优先级应下调(如优先数加3)。

7、启动自动调度,系统时间单位开始自动计时,系统开始自动调度执行。程序显示每个时间单位的各个队列的 PCB信息。

8、最后输出每个进程的周转时间。

三、再学轮转调度算法

操作系统第三章—处理机调度及调度算法_每天八杯水的博客-CSDN博客

四、编程

运行环境:Visual Studio 2019

编程语言:c、c++

逻辑图:

代码:

#include <iostream>
using namespace std;
typedef int DataType;/*全局变量
*/
int process_count;//输入进程数
int syProcess = process_count;//剩余进程数量
int sjp_Time;//时间片大小
int os_time=0;//系统时间/*定义PCB的结构体
*/
struct node     //结构标记
{char name; //进程名DataType arrive_time;  //进程进入系统的到达时间DataType run_time;     //进程要求运行的时间DataType yjyx_time;      //进程已经运行的时间DataType state;          //进程状态3种,0表示未进入状态,1表示就绪状态,2表示完成状态DataType Priority;        //优先数DataType zz_time;      //进程周转时间DataType wc_time;       //进程完成结束时间struct node* next;        //意味着next能存储一个指向该结构体的指针(要求使用结构标记才能用这个,不能用typedef)
}process[10];               //结构体数组,用于后面第一次给就绪队列排序辅助用的/*定义三个指向结构体的指针,分别用于三个队列的首节点,便于操作
*/
struct node* noEnter = (struct node*)malloc(sizeof(struct node));  //这是相当于声明了一个指向结构体的指针变量—未进入队列的头结点
struct node* runList = (struct node*)malloc(sizeof(struct node));  //就绪队列
struct node* wcList  = (struct node*)malloc(sizeof(struct node));  //完成队列typedef struct node *PCB;//给struct node取了一个简单名字,减少struct node*的写法/*初始化进程的PCB信息,存入未进入队列noEnter
*/
void Initia(PCB head) {struct node* q;q = head;/*循环创建新节点空间并赋值,且存入结构体数组process[]*/for (int i = 0; i < process_count; i++) {PCB p = (PCB)malloc(sizeof(struct node));cout << "第" << i + 1 << "个进程PCB信息:";cin >> p->name >> p->arrive_time >> p->run_time >> p->Priority;p->state = 0;        //状态初始化为0未开始运行p->yjyx_time = 0;process[i].name = p->name;process[i].arrive_time = p->arrive_time;process[i].run_time = p->run_time;process[i].Priority = p->Priority;process[i].state = p->state;q->next = p;q = p;}q->next = head->next;   //末尾PCB指向第一个节点PCB,实现单向循环队列
}/*打印未进入、就绪队列中PCB的信息
*/
void Show(PCB head) {PCB p = head->next;PCB q = p->next;//cout << "     *********进程信息*********" << endl;cout << "     进程名 到达时间 运行时间 已运行时间 优先数" << endl;//for(int i=0;i<process_count;i++)//{//    cout << "\t" << p->name << "\t";// cout << p->arrive_time << "\t";//  cout << p->run_time << "\t";// cout << p->Priority << endl;//   p = p->next;//最后一个PCB输出后,p将指向第一个PCB//}do{cout << "\t" << p->name << "\t";cout << p->arrive_time << "\t";cout << p->run_time << "\t   ";cout << p->yjyx_time << "\t    ";cout << p->Priority << endl;p = p->next;//最后一个PCB输出后,p将指向第一个PCB} while (p != head->next);cout << endl;}/*打印完成队列中PCB的信息
*/
void ShowWcList(PCB wclist) {PCB p = wclist->next;cout << "          *********完成进程信息*********" << endl;cout << "     进程名 到达时间 运行时间 优先数 完成时间 周转时间" << endl;//for (int i = 0; i < process_count; i++)//{//  cout << "\t" << p->name << "\t";// cout << p->arrive_time << "\t";//  cout << p->run_time << "\t";// cout << p->Priority << "\t";// cout << p->zz_time << endl;//    p = p->next;//最后一个PCB输出后,p将指向第一个PCB//}do{cout << "\t" << p->name << "\t";cout << p->arrive_time << "\t";cout << p->run_time << "\t";cout << p->Priority << "\t";cout << p->wc_time << "\t";cout << p->zz_time << endl;p = p->next;//最后一个PCB输出后,p将指向第一个PCB } while (p!=wclist->next);cout << endl;
}/*给就绪队列第一个排序时用的排序算法,因为要创建新节点,所以借用结构体数组process来赋值
*/
void sortRunList(PCB runList) {//按照优先数大小排序-直接对noEnter队列进行比较,最小的优先数放第一个节点//重新排序process数组int i, j, n = process_count;for (i = 0; i < n - 1; i++){ for (j = 0; j < n - 1 - i; j++){if (process[j].Priority > process[j + 1].Priority){process[n] = process[j + 1];process[j + 1] = process[j];process[j] = process[n];}}}//赋值给runList队列PCB q = runList;for (int i = 0; i < process_count; i++) {PCB p = (PCB)malloc(sizeof(struct node));p->name = process[i].name;p->arrive_time = process[i].arrive_time;p->run_time = process[i].run_time;p->Priority = process[i].Priority;p->state = 1;          //状态为1,就绪状态p->yjyx_time = 0;     //已经运行时间初始化为0q->next= p;q = p;}q->next = runList->next;
}/*重新设计排序算法,以runlist为对象,以链表排序sortRunList排序算法已经给runlist创建了空间并排序,在RR()中runlist中的结点迟早会被删除完。怎么给链表排序???
*/
void sortRunList2(PCB runList) {PCB pre = runList;PCB p = runList->next;PCB q = p->next;//只需要判断前一个进程的优先数是否大于后一个进程的优先数//while (q!=runList->next)    //当q为第一个进程时循环结束//{//    if (p->Priority > q->Priority) {//     pre->next = q;//        p->next = q->next;//     q->next = p;//      //重定位pre p q//      pre = q;//     q = p->next;//  }// else//  {//     pre = p;//     p= q;//        q = p->next;//  }       //}for (int i = 0; i < syProcess; i++){//当q为第一个进程时循环结束if (p->Priority > q->Priority) {pre->next = q;p->next = q->next;q->next = p;//重定位pre p qpre = q;q = p->next;}else{pre = p;p = q;q = p->next;}}   }/*轮转调度算法
*/
void RR(PCB runlist) {int sum=0;     //已经完成的进程数量PCB p= runList->next;PCB q = runList;PCB wc = wcList;int sjp_count = 1;while(sum<process_count) {/*如果该进程优先数最小,优先级最大,并且到达时间小于等于此时系统时间,就执行该进程,给它一个时间片,已经运行时间=时间片*/if (p->arrive_time <= os_time) {      //开始执行/*1、判断此刻能不能在一个时间片内完成判断条件:运行时间-已经运行时间 <= 时间片若能:则要从就绪队列中删除该进程,放入完成队列系统时间=原系统时间 + 最后一次所需要的运行时间(等于要求运行时间 - 已经运行时间)进程完成时间=此时的系统时间若不能:优先数+3,当前指向进程的CPU资源给下一个进程系统时间=原系统时间 + 一个时间片大小每执行一次进程,都有判断该进程是否是就绪队列最后一个若是最后一个:重新排序就绪队列*/if ((p->run_time-p->yjyx_time) <= sjp_Time) {           //如果一个时间片就能完成sum = sum + 1;os_time = os_time +( p->run_time - p->yjyx_time);  //此时就是该进程的完成时间p->wc_time = os_time;p->zz_time = os_time - p->arrive_time;                //周转时间=系统时间-到达时间//一个时间片就完成的话,就要删除该进程,放入完成队列,且sum+1//接着把该进程放入完成队列中wcList,先放入完成队列中,再删除原就绪队列中的节点,不然数据丢失了PCB t= (PCB)malloc(sizeof(struct node));wc->next = t;t->arrive_time = p->arrive_time;t->name = p->name;t->run_time = p->run_time;t->wc_time = p->wc_time;t->zz_time = p->zz_time;t->state = 2;t->Priority = p->Priority;wc = t;wc->next = wcList->next;//删除该进程q->next = p->next;p= p->next;syProcess--;/*cout << "=========================================" << endl;cout << "执行完的进程从就绪队列中删除,剩余就绪队列进程"<<endl;Show(runList);cout << "=========================================" << endl;*//*   编程过程中的问题分析:查看runlist里面有没有删除完成进程,,,发现并未被删除——发现是下面else里面q赋值错误,q = p;写在了p = p->next;的后面导致的还要删除process[]中的。后面才能继续排序——不用此方法,改为直接修改链表排序试试不删除输出是怎么样的。????——根据排序算法,不删除就会把所有进程再重新赋值给runlist队列,不可行——此方法不用了*/          }//运行一个时间片内还未完成—当某一进程运行完一个时间片后,其优先级应下调,加3else{os_time = os_time + sjp_Time;p->yjyx_time = p->yjyx_time+sjp_Time;//已经运行时间=之前的已经运行时间+时间片,继续在一个时间片执行的进程,已经运行时间就时间片p->Priority = p->Priority +3;//优先数变了,就要重新排序q = p;p = p->next;/*process[countnode].Priority = p->Priority;//解决排序后的priority不变的问题——不用此方法了,重新设计新的利用链表修改排序sortRunList(runList);//对就绪队列排序不应该在此时重新排序,应该是先遍历一遍所有就绪队列,然后重新排序sortRunList2(runList);-----------此处排序不能再使用这个了,因为该排序使用的还是process里面的数据,此时的priority已经改变局还没看cout << "=========================================" << endl;cout << "------调整优先数后重新排序的进程信息------"<<endl;Show(runList);//会发现重新排序后已经完成的进程还在runlist队列中cout << "=========================================" << endl;????????????????????????????????要修改这里此处有问题——重新排序后,p的指针还是只想修改优先级的进程上的,但是此时优先数改变了,该进程的位置也向后面调整了就没有从未改变位置时的后面一个进程开始遍历,直接跳过了原位置到修改位置后中间的所有进程改进方法:在排序前切换到下一个就绪队列中的进程q = p;p = p->next;*/}//======== = 执行完一次进程,即执行完一个时间片了,可以显示打印一下此时所用进程的信息========cout << "===============第" << sjp_count << "个时间片内=============" << endl;sjp_count++;Show(runlist);}  //if结束 else//若该进程还未到达时间,就执行下一个进程{q = p;p = p->next;}/*如果p到了第一个进程,也就是说第一遍遍历完了后就要重新排序—轮转调度算法要先把就绪队列遍历完,在根据重新排序的就绪队列来再遍历调度*/if (p == runlist->next) {/*    cout << "===============第" << sjp_count << "个时间片内=============" << endl;sjp_count++;*/sortRunList2(runList);/*cout << "=========================================" << endl;cout << "------调整优先数后重新排序的就绪队列进程信息------"<<endl;Show(runList);cout << "=========================================" << endl;*/}}//while结束
}
void main() {cout << "请输入进程数量:";cin >> process_count;cout << "请输入时间片大小:";cin >> sjp_Time;Initia(noEnter);cout << "------未进入队列的进程信息------" << endl;Show(noEnter);//显示未进入队列sortRunList(runList);//对就绪队列排序cout << "------刚开始的就绪队列的进程信息------" << endl;Show(runList);//显示就绪队列RR(runList);ShowWcList(wcList);system("pause");
}

运行结果:

操作系统实验1—基于优先数的时间片轮转调度算法调度处理模拟程序设计相关推荐

  1. 计算机操作系统实验之进程调度(一)轮转调度法(C语言)

    计算机操作系统实验之进程调度(一)轮转调度法(C语言) 实验目的 实验内容与基本要求 轮转调度法的基本原理 实现思路及功能分析 算法流程图 全部代码 工程图 ProcessScheduling.h P ...

  2. Java模拟操作系统实验一:四种进程调度算法实现(FCFS,SJF,RR,HRN)

    前言 刚学完操作系统,模拟实现了其中一些经典的算法,内容比较多,打算写一个系列的总结,将自己的源码都分享出来,既方便自己以后复习,也希望能帮助到一些刚入坑的小伙伴.我的所有代码的运行环境都是基于Ecl ...

  3. 操作系统实验五 基于内核栈切换的进程切换(哈工大李治军)

    实验5 基于内核栈切换的进程切换 实验目的 深入理解进程和进程切换的概念: 综合应用进程.CPU 管理.PCB.LDT.内核栈.内核态等知识解决实际问题: 开始建立系统认识. 实验内容 现在的 Lin ...

  4. 基于C++的微流控生物芯片模拟程序设计

    目录 微流控生物芯片模拟程序设计文档 1 程序介绍 1 现实背景 1 设计目的 1 程序使用方法 3 testcaseerror.txt测例自行测试,效果为 9 程序设计 11 技术基础 11 类的职 ...

  5. 操作系统 实验3【动态分区存储管理】

    操作系统 实验1[短作业优先调度算法(C++实现--FCFS\SJF\HRRN)] 操作系统 实验2[动态高优先权优先调度算法 C++实现] 操作系统 实验3[动态分区存储管理 Python实现] 操 ...

  6. 操作系统实验二(调度算法模拟-先进先出-时间片轮转法-优先服务调度算法)

    实验二 进程调度 一.     实验目的 1.       理解进程运行的并发性. 2.       理解处理器的三级调度. 3.       掌握先来先服务的进程调度算法. 4.       掌握短 ...

  7. 时间片轮转RR进程调度算法(操作系统实验 C+)

    时间片轮转RR进程调度算法 1.实验目的 通过这次实验,加深对进程概念的理解,进一步掌握进程状态的转变.进程调度的策略及对系统性能的评价方法. 2.实验内容 问题描述: 设计程序模拟进程的时间片轮转R ...

  8. 操作系统实验之时间片轮转RR进程调度算法

    一.实验内容 设计程序模拟进程的时间片轮转RR调度过程.假设有n个进程分别在T1, - ,Tn时刻到达系统,它们需要的服务时间分别为S1, - ,Sn.分别利用不同的时间片大小q,采用时间片轮转RR进 ...

  9. 《操作系统》实验三:高响应比优先调度和时间片轮转RR进程调度算法

    [实验题目]:高响应比优先调度和时间片轮转RR进程调度算法 [实验学时]:4学时 [实验目的] 通过这次实验,加深对进程调度概念的理解,进一步掌握比FCFS和SJF更为复杂的进程调度算法的实现方法. ...

  10. 操作系统实验二——时间片轮转调度算法(RR算法)(新进程放队首和队尾两种C++实现)

    情况介绍 基本原理 系统将所有就绪进程按照FCFS的原则,排成一个队列依次调度. 把CPU分配给队首进程,执行一个时间片(10-100ms). 时间片用完后,系统计时器发出时钟中断,该进程将被剥夺CP ...

最新文章

  1. 创业笔记-Node.js入门之阻塞与非阻塞
  2. 深入掌握JMS(一):JMS基础
  3. 详解|清华大学100页PPT:工业机器人技术详解
  4. 30分钟后如何终止PHP会话?
  5. s2sh集成dataSource配置无效的问题 -Access denied for user 'sa'@'localhost'
  6. 代码生成器的存在价值 选择自 mechiland 的 Blog
  7. Vs快捷键设置(可搭配Vim使用)
  8. SQL Search
  9. 零基础带你学习MySQL—修改表(六)
  10. Centos6.3搭建cactinagios
  11. 非常好的Demo网站
  12. Dennis Ritchie, father of Unix and C, dies
  13. 以删除重建的方式修复托管磁盘虚拟机
  14. DevCon 5 2019 活动照片
  15. 浪潮服务器dhcp修改ip,IP地址管理—DDI(DNS, DHCP, IPAM)解决方案
  16. 微信小程序 基本认识
  17. 关于 RocketMQ:The producer group has been created before, specify another name please.这个报错的解决办法...
  18. 等额本金和等额本息房贷公式推导
  19. 国美股价大跌围殴顾客? 此前四曝殴打消费者
  20. Lasso-Logistic回归-R语言应用详解

热门文章

  1. Linux 指令篇:档案目录管理--ls
  2. php 制作网站地图,网站地图怎么做,制作网站地图的三种实用方法
  3. java jsp试卷_JSP试题-带答案
  4. 2021 浏览器edge改 ie11 模式
  5. wifi分析仪怎么看哪个信道好_一定得学的切换WiFi信道技巧,让你的网速如飞!...
  6. sql注入工具--Sqlmap
  7. Unity3D AI:导航系统-导航网格生成
  8. Transcad学习记
  9. 苹果cmsV10资源站模板
  10. 基于STM32移植UCGUI图形界面框架(3.9.0源码版本)