操作系统-进程调度--优先级调度算法和时间片轮转算法_时间片轮转流程图-程序员宅基地

技术标签: c++  操作系统  

一、实验内容与要求

  1. 优先权法、轮转法
    简化假设
    1)进程为计算型的(无I/O)
    2)进程状态:ready、running、finish
    3)进程需要的CPU时间以时间片为单位确定
  2. 算法描述
    1)优先权法——动态优先权
    当前运行进程用完时间片后,其优先权减去一个常数。
    2)轮转法
  3. 要求
    1)产生的各种随机数的取值范围加以限制,如所需的CPU时间限制在1~20之间。
    2)进程数n不要太大通常取4~8个
    3)使用动态数据结构
    4)独立编程

二、实验流程图
在这里插入图片描述在这里插入图片描述
三、实验分析

优先权调度算法
首先,时间片轮转法需要实时根据优先权大小对进程排序,优先级大的进程先运行,所以采用优先队列的数据结构是最合适的。
PCB中还需要存放进程的名称、进程的所需时间、进程的优先权、进程的状态,可以采用结构体,同时还可以自定义进程的排序方式。
初始化时,进程的所需时间范围规定为1-20;又因为每个时间片结束,进程所需时间-1,优先权-3,为使优先级不小于0,规定优先级为60-80;进程的初始状态都为ready。
采用优先级调度算法时,每次先将队首进程状态置为running,然后输出各进程的状态。若此时队首的进程状态都为finish,则代表全部的进程都已经完成,即退出;否则时间片到后,进程所需时间-1,优先权-3,再继续判断进程是否已经完成,若完成,则将进程的优先权置为最小的0后入队,保证在优先队列中,该进程总是在队尾的。
时间片轮转算法
轮转法要注意理解轮转时间片的概念,轮转时间片规定了该进程每次最多可运行的时间片数。
在轮转法中,若已占用的时间片<轮转时间片,那么该进程一直在队首占用CPU运行,采用普通的队列,每次队首出列后,只能在队尾弹入,所以我采用了双端队列的数据结构,这样在占用时间片<轮转时间片的情况下,进程可以直接弹入队首,减少了时间复杂度和空间复杂度。
另外,在轮转法中,进程完成后无法像优先队列那样一直在队尾,所以我另外开了一个队列,存放已完成的进程情况。

四、实验代码

#include <bits/stdc++.h>

using namespace std;

//*************************优先级调度算法****************************//

struct PCB_PSA {
    
    int id;             //进程名称
    int need_time;      //进程所需时间
    int priority;       //进程的优先级
    string state;       //进程的状态

    //优先队列排序,优先级大的进程先执行
    bool operator<(const PCB_PSA &a) const {
    
        return a.priority >= priority;
    }
};

int cnt = 1;            //记录时间
int n;                  //进程个数
char c;                 //选择调度算法
priority_queue<PCB_PSA> pcb_PSA;

//进程初始化
void init_PSA() {
    
    for (int i = 1; i <= n; i++) {
    
        PCB_PSA t;
        t.id = i;
        t.need_time = rand() % 20 + 1;      //进程所需时间为1~20
        t.priority = rand() % 20 + 60;      //进程优先权为60~80,因为每执行一个时间片优先权-3,优先权很快会变成负数,采用这个范围的话优先权最小为0
        t.state = "ready";                  //进程状态初始化为ready
        pcb_PSA.push(t);
    }
}

//输出当前进程运行情况
void print_PSA() {
    
    priority_queue<PCB_PSA> temp = pcb_PSA;
    PCB_PSA t;
    cout << endl << "当前时刻:" << cnt++ << endl;
    while (!temp.empty()) {
    
        t = temp.top();
        temp.pop();
        cout << "进程名称:" << t.id << "\t状态:" << t.state << "\t所需时间:" << t.need_time << "\t优先级:" << t.priority << endl;
    }
}

//优先级调度
void PSA() {
    
    PCB_PSA t;
    while (1) {
    
        //将队首进程状态改为running,然后输出进程执行情况
        t = pcb_PSA.top();
        pcb_PSA.pop();
        if (t.state != "finish")t.state = "running";
        pcb_PSA.push(t);
        print_PSA();
        t = pcb_PSA.top();
        pcb_PSA.pop();
        //若队首进程的状态为finish,则进程全部完成,退出。
        if (t.state == "finish")break;
        //时间片到,进程所需时间-1,优先权-3
        t.need_time -= 1;
        t.priority -= 3;
        //若进程所需时间为0,则将优先权置为最小0;否则状态变为ready。
        if (t.need_time == 0) {
    
            t.state = "finish";
            t.priority = 0;
        } else {
    
            t.state = "ready";
        }
        pcb_PSA.push(t);
    }
}

//********************************************************************//
//***************************时间片轮转调度算法***************************//

struct PCB_RR {
    
    int id;                 //进程名称
    int need_time;          //进程所需时间
    int round_time;         //进程轮转时间片
    int hold_time;          //进程占已用时间
    string state;           //进程状态
};
//pcb_finish存放已经完成的进程
deque<PCB_RR> pcb_RR, pcb_finish;


//进程初始化
void init_RR() {
    
    for (int i = 1; i <= n; i++) {
    
        PCB_RR t;
        t.id = i;
        t.need_time = rand() % 20 + 1;      //进程所需时间范围为1~20
        t.round_time = rand() % 20 + 1;     //进程轮转时间片为1~20
        t.hold_time = 0;                    //进程占用时间初始化为0
        t.state = "ready";                  //进程状态初始化为ready
        pcb_RR.push_back(t);
    }
}

//输出当前进程运行情况+已完成的进程情况
void print_RR() {
    
    cout << endl << "当前时刻:" << cnt++ << endl;
    deque<PCB_RR> temp = pcb_RR;
    PCB_RR t;
    while (!temp.empty()) {
    
        t = temp.front();
        temp.pop_front();
        cout << "进程名称:" << t.id << "\t状态:" << t.state << "\t所需时间:" << t.need_time << "\t轮转时间片:" << t.round_time << endl;
    }
    temp = pcb_finish;
    while (!temp.empty()) {
    
        t = temp.front();
        temp.pop_front();
        cout << "进程名称:" << t.id << "\t状态:" << t.state << "\t所需时间:" << t.need_time << "\t轮转时间片:" << t.round_time << endl;
    }
}

//轮转时间片
void RR() {
    
    PCB_RR t;
    while (!pcb_RR.empty()) {
    
        //将队首进程状态改为running,然后输出当前进程执行情况
        t = pcb_RR.front();
        pcb_RR.pop_front();
        t.state = "running";
        pcb_RR.push_front(t);
        print_RR();
        t = pcb_RR.front();
        pcb_RR.pop_front();
        //时间片到,进程所需时间-1,进程占用时间+1
        t.need_time -= 1;
        t.hold_time += 1;
        //若进程所需时间为0,则进程执行完成,入pcb_finish队列
        //若占用时间=轮转时间片,进程占用时间置0,入队尾
        //否则进程入队首
        if (t.need_time == 0) {
    
            t.state = "finish";
            pcb_finish.push_back(t);
        } else if (t.hold_time == t.round_time) {
    
            t.state = "ready";
            t.hold_time = 0;
            pcb_RR.push_back(t);
        } else {
    
            pcb_RR.push_front(t);
        }
    }
    print_RR();
}

//*********************************************************************//

int main() {
    
    srand(time(NULL));
    cout << "请输入进程数(4~8个):";
    cin >> n;
    cout << "请选择调度方法(y:优先权法;n:轮转法):";
    cin >> c;
    if (c == 'y') {
    
        init_PSA();
        PSA();
    } else if (c == 'n') {
    
        init_RR();
        RR();
    }
    return 0;
}
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_44019380/article/details/117397900

智能推荐

以MapBox为核心构建Vue地图组件库教程_vue 省份 地图组件库-程序员宅基地

文章浏览阅读951次。不多废话直接讲干货,首先我们要清楚如何写一套组件库,类似于使用vue编写的elementui,使用react编写的antdesign等,我们现在要以GIS为核心写组件库,其实原理类似。一个是组件的主体vue文件,另一个是将组件局部暴露出去的index.js文件,当然你可以再此基础上增加你想要的其他的js文件和vue文件,上面讲的两个文件是必须的。这行命令可以将你写的组件库打包成压缩文件,一般是一个dist静态目录,在进行npm发布的时候也是将这个静态的dist发布在官网上。_vue 省份 地图组件库

【控制control】四足机器人弹簧加载倒立摆(SLIP)动力学模型_【控制control】四足机器人动力学模型-slip-程序员宅基地

文章浏览阅读4.9k次,点赞5次,收藏32次。系列文章目录提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加TODO:写完再整理文章目录系列文章目录前言1.动力学建模构型方法2.四足机器人动力学模型(1)多体动力学模型【针对躯干+脚建模】方法一:VMC( Virtual Model Controller)模型方法二:SLIP模型(2)浮基单体动力学模型【针对躯干建模】【用于MPC】前言认知有限,望大家多多包涵,有什么问题也希望能够与大家多交流,共同成长!本文先对四足机器人动力学模型-VMC、SLIP和浮动机体模型做个简_【控制control】四足机器人动力学模型-slip

html5手指点击速度,CPS手速测试 - 鼠标点击速度测试插件-程序员宅基地

文章浏览阅读1.2w次。CPS手速测试插件背景简介为了刺激客户的消费很多购物平台都推出来秒杀抢购的活动,在这个活动中如果你的手速慢就抢不到商品,所以有时我们会需要锻炼一下自己的手速,那如何知道自己的手速是快还是慢呢,在世界平均范围中又处于何种地步,今天小编为大家推荐一款可以检测自己手速的插件CPS手速测试。CPS手速测试插件简介CPS手速测试插件是一款可以在线测试鼠标点击速度的检测工具,它可以是1/3/5/10/15/3..._测速度插件

VLAN以及三层交换机_核心交换机如何查询vlan-程序员宅基地

文章浏览阅读2k次,点赞2次,收藏7次。VLAN以及三层交换机1、VLAN概述与优势1.1vlan概述1.2vlan优势1.3VLAN的分类Trunk概述三层交换技术1、VLAN概述与优势1.1vlan概述VLAN(Virtual Local Area Network),中文称为虚拟局城网。是一组逻辑上隔离的设备和用户。这些设备和用户不受物理位置限制,可根据部门成组等进行灵活划分,保障信息安全。同时隔绝广播信息,提升网络效能,防止广播风暴的产生。1.2vlan优势1. 限制广播域。广播域被限制在一个VLAN内,提高了网络处理能力。 2_核心交换机如何查询vlan

clearTimeout无效_cleartimeout不生效-程序员宅基地

文章浏览阅读7.3k次。如图所示clearTimeout接受id作为参数,所以检查一下是否传入的不是id因为默认情况下setTimeout方法是会返回id但有时候会返回一个setTimeout对象比如使用vsCode 开发的同学在使用setTimeout时会自动引入timer对象,此时setTimeout就会返回Timeout对象,此时只需要将对应的id传入即可或者直接将引用注掉..._cleartimeout不生效

安卓发送post请求_android post-程序员宅基地

文章浏览阅读1.6k次。在HTTP通信中使用最多的就是GET和POST了,GET请求可以获取静态页面,也可以把参数放在URL字符串的后面,传递给服务器。本文将使用标准Java接口HttpURLConnection,以一个实例演示如何使用POST方式向服务器提交数据,并将服务器的响应结果显示在Android客户端。在Android中,提供了标准Java接口HttpURLConnection和Apache接口HttpClient,为客户端HTTP编程提供了丰富的支持。将提交的数据写入Log\Log.php文件中。_android post

随便推点

HDU - 1272 小希的迷宫之独木桥(并查集的简单应用)-程序员宅基地

文章浏览阅读236次。小希的迷宫 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)_hdu - 1272

RAD Studio 11.2详解其务实改进(Delphi & C++ Builder)-Alexandria-程序员宅基地

文章浏览阅读7.4k次,点赞5次,收藏11次。● 开发人员生产力:“搬运式的复用”是一个特性。使用Delphi和C++Builder使得开发机构交付订单和市场需求的速度提高了5倍有余。● 快速的“原生”应用程序:操作系统本机的原生编译器,赋能App应用应有的原生速度(没有任何臃肿)。● 数据库访问:Delphi最原始的关键设计之一,就是将数据库访问完全集成到RAD Studio之中。● 强大的C++库:数百个C++库,可以在C++Builder中使用,或者在RAD Studio中的Delphi下使用。_rad studio

shiro@RequiresPermission校验实现_requirespermissions 校验的是-程序员宅基地

文章浏览阅读864次。shiro-spring借助Spring AOP特性实现shiro的注解式校验引入shiro-spring依赖后一定要注入AuthorizationAttributeSourceAdvisor以便借助spring aop进行shiro注解校验 @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) ..._requirespermissions 校验的是

唱响中国-红歌36首-刘和刚 - 好男儿就是要当兵-程序员宅基地

文章浏览阅读308次。歌曲下载/歌词下载:http://dl.iteye.com/topics/download/be412093-1ed9-3086-aeaf-e132ca9a1758刘和刚 - 好男儿就是要当兵歌词:好男儿就是要当兵刘和刚唱响中国-红歌36首当兵才知道帽徽为什么这样红当兵才知道肩章为什么这样重当兵才知道祖国的山河在心中咱当了兵才知道好男儿 嘿 就是要当兵当兵才知道过去的模样太放松当兵..._当兵的人才知道自己的骨头有多硬

探索iOS转场动画_ios 转场动画-程序员宅基地

文章浏览阅读1.5k次,点赞2次,收藏3次。iOS提供图像转场动画,可实现酷炫的转场特效。动画包括:溶解、折叠、复印机、闪烁、翻页、波纹、滑动等等。_ios 转场动画

Java 本地内存 & 直接内存 & 元空间_java 本地内存和直接内存-程序员宅基地

文章浏览阅读4.1k次,点赞7次,收藏26次。Java虚拟机在执行的时候会把管理的内存分配到不同的区域,这些区域称为虚拟机内存;同时对于虚拟机没有直接管理的物理内存,也会有一定的利用,这些被利用但不在虚拟机内存的地方称为本地内存。元空间不在虚拟机中,而是使用本地内存,JVM不会再出现方法区的内存溢出问题。..._java 本地内存和直接内存