基于优先级的时间片轮转调度算法(C语言实现)

news2025/7/19 16:53:05

已剪辑自: http://www.demodashi.com/demo/15341.html

基于优先级的时间片轮转调度算法

1. PCB结构(Block)

pcb

由此定义如下结构体:

typedef struct Block
{
    int processID; // 进程号
    int priority; // 优先级
    int status; // 状态
    double arrivalTime; // 到达时间
    double serviceTime; // 服务时间
    double runTime; // 已运行时间
    struct Block *next; // Next Block
} Block;

2. 数据结构(队列)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pvXuaPmI-1669459048842)(/contentImages/image/jianshu/13373683-fc06e9117b622d3e.png)] ](http://www.demodashi.com/contentImages/image/jianshu/13373683-ad1ac427688c2f40.png)

typedef struct Link
{
    struct Block *first;  // 指向队头
    struct Block *last;   // 指向队尾
} Link;

队列操作函数:

  • initLink:初始化队列
void initLink(Link *l)
{
    // 分配空间并检测是否成功
    l->first = l->last = (Block *)malloc(sizeof(Block));
    if (!l->first)
    {
        fprintf(stderr, "Malloc Error!\n");
        exit(-1);
    }
    // 空队列
    l->first->next = NULL;
    l->last->next = NULL;
}
  • isEmpty:判断队列是否为空
int isEmpty(Link *l)
{
    return l->first->next == NULL? 1: 0;
}
  • printLInk:输出队列中所有元素的信息
void printLink(Link *l)
{
    Block *p = l->first->next;
    // 遍历队列并输出
    printf ("\nProcess ID\tPriority\tArrival Time\tService Time\tRun Time\tStatus\n");
    while (p != NULL)
    {
        printf("\t%d\t%d\t\t%.2lf\t\t%.2lf\t\t%.2lf\t\t%s\n", \
            p->processID, p->priority, p->arrivalTime, \
            p->serviceTime, p->runTime, p->status == 0? "ready": "finished");
        p = p->next;
    }
}
  • removeFirst:将队列中第一个元素中的数据复制到给定参数中(用于返回),并删除
void removeFirst(Link *l, Block *b)
{
    Block *t;
    // 空队列则直接返回
    if (isEmpty(l))
    {
        return ;
    }
    // t指向第二个Block,用于之后将队列接上
    t = l->first->next->next;
    // 将第一个Block中的内容复制到b中,用于返回
    b->processID = l->first->next->processID;
    b->priority = l->first->next->priority;
    b->arrivalTime = l->first->next->arrivalTime;
    b->serviceTime = l->first->next->serviceTime;
    b->runTime = l->first->next->runTime;
    b->status = l->first->next->status;
    // 释放第一个Block,并把队列接上
    free (l->first->next);
    l->first->next = t;
}
  • append:将新的元素添加到队尾
void append(Link *l, Block *b)
{
    Block *t;
    // 分配空间,并检测是否成功
    t = (Block *)malloc(sizeof(Block));
    if (t == NULL)
    {
        fprintf(stderr, "Malloc Error!\n");
        exit(-1);
    }
    // 将b中的内容复制到t中
    t->processID = b->processID;
    t->priority = b->priority;
    t->arrivalTime = b->arrivalTime;
    t->serviceTime = b->serviceTime;
    t->runTime = b->runTime;
    t->status = b->status;
    // 将t接到队尾
    t->next = NULL;
    l->last->next = t;
    l->last = t;
}
  • deleteLinkItem:删除队列中指定的元素
void deleteLinkItem(Link *l, Block *target)
{
    Block *p, *t;
    // 遍历队列,寻找目标Block
    p = l->first;
    while (p != NULL && p != target)
    {
        t = p;
        p = p->next;
    }
    // 若存在,则释放
    if (p != NULL)
    {
        t->next = p->next;
        free(p);
    }
}
  • sortByArrivalTime:根据进程到达时间将队列排序(从小到大)
void sortByArrivalTime(Link *l, int order)
{
    Block *p, *q, *tp, *tq;
    Block *temp, *min, *tmin;
    int minArrivalTime;
    // 这里使用了选择排序
    tp = tq = l->first;
    p = q = l->first->next;
    while (p != NULL)
    {
        // 这个数字可以修改的大一点。。。
        minArrivalTime = 9999;
        while (q != NULL)
        {
            // 寻找最小到达时间的Block
            if (q->arrivalTime < minArrivalTime)
            {
                minArrivalTime = q->arrivalTime;
                tmin = tq;
                min = q;
            }
            tq = q;
            q = q->next;
        }
        // 若寻找的Block与当前Block不是同一个则交换
        if (p != min)
        {
            tp->next = min;
            tmin->next = p;
            temp = min->next;
            min->next = p->next;
            p->next = temp;
        }
        tp = tq = p;
        p = q = p->next;
    }
}

3. 基于优先级的时间片轮转调度算法

  • 流程图

流程图

  • 算法
void RR(Link *l, Link *r)
{
    Block *p, *t;
    double maxPriority;
    double currentTime = 0;
    int selected, timeSlice;
    // 种下随机种子
    srand((unsigned)time(NULL));
    // 遍历队列
    t = p = l->first->next;
    while (p != NULL)
    {
        // 输出在当前时间已到达的进程Block信息
        printf ("\nProcess ID\tPriority\tArrival Time\tService Time\tRun Time\tStatus\n");
        selected = 0;
        maxPriority = 9999;
        while (p != NULL && currentTime >= p->arrivalTime)
        {
            selected = 1;
            printf("\t%d\t%d\t\t%.2lf\t\t%.2lf\t\t%.2lf\t\t%s\n", \
                p->processID, p->priority, p->arrivalTime, \
                p->serviceTime, p->runTime, p->status == 0? "ready": "finished");
            // 寻找优先级最高的进程
            if (p->priority < maxPriority)
            {
                maxPriority = p->priority;
                t = p;
            }
            p = p->next;
        }
        // 生成随机时间片
        timeSlice = rand() % 10;
        if (selected)
        {
            // 运行进程(模拟)
            printf("Current time: %.0lf, Selected process: %d\n", currentTime, t->processID);
            t->runTime += timeSlice;
            t->priority += 2;
            // 若进程已经结束,则将该进程添加到完成队列,并从当前队列中删除
            if (t->runTime >= t->serviceTime)
            {
                t->status = 1;
                currentTime += t->serviceTime - (t->runTime - timeSlice);
                t->runTime = t->serviceTime;
                append(r, t);
                deleteLinkItem(l, t);
            }
        }
        else
        {
            currentTime += timeSlice;
        }
        // 打印完成队列
        printLink(r);
        t = p = l->first->next;
    }
}

4. 测试与结果

  • 测试数据

测试数据

  • 测试结果

1

2

3

4

5

5.项目结构图

项目结构图
img

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/37818.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PyQt5 JavaScript调用PyQt代码

JavaScript调用PyQt代码JavaScript调用PyQt代码,是指PyQt可以与加载的Web页面进行双向的数据交互。1.创建QWebChannel对象&#xff1a;创建QWebChannel对象&#xff0c;注册一个需要桥接的对象&#xff0c;以便Web页面的JavaScript使用。其核心代码如下&#xff1a;channel QW…

JUC并发编程与源码分析笔记01-本课程前置知识及要求说明

JUC是什么 JUC是指java.util.concurrent包&#xff0c;在并发编程中广泛使用。 官方文档搜索java.util.concurrent&#xff0c;可以看到有java.util.concurrent、java.util.concurrent。atomic、java.util.concurrent.locks。 本课程学生对象&#xff08;非零基础&#xff09…

记 linux 系统编译好的exp提权提示无gcc

文章目录CVE-2021-4034 漏洞 polkit 提权在目标linux主机没有gcc的情况下提权&#xff0c;在很多情况下的一些内核漏洞需要在目标主机上使用gcc编译才可以正常运行&#xff0c;在本地编译好的exp如果本地系统与目标主机系统不一致&#xff0c;上传执行很大机会导致系统崩溃如脏…

糟了,线上服务出现OOM了

前言 前一段时间&#xff0c;公司同事的一个线上服务OOM的问题&#xff0c;我觉得挺有意思的&#xff0c;在这里跟大家一起分享一下。 我当时其实也参与了一部分问题的定位。 1 案发现场 他们有个mq消费者服务&#xff0c;在某一天下午&#xff0c;出现OOM了&#xff0c;导…

docker技术简介

目录 概念 命令 数据卷 DockerFile 应用部署 服务编排 私有仓库 概念 Docker 是一个开源的应用容器引擎&#xff0c;而容器技术是一种轻量级虚拟化方案&#xff08;虚拟机太繁重了不够轻量级&#xff09;&#xff0c;Docker的基础是Linux容器&#xff08;LXC&#xff09…

离线安装ceph集群(ceph-13.2.10)

记录&#xff1a;332 场景&#xff1a;在CentOS 7.9操作系统上&#xff0c;使用ceph的rpm-mimic的ceph-13.2.10安装ceph集群。应用ceph对象存储(ceph object store)&#xff1b;应用ceph块设备(ceph block device)&#xff1b;应用ceph文件系统(ceph file system)。 版本&…

数据结构(5)树形结构——二叉搜索树(JAVA代码实现)

5.1.概述 二叉搜索树&#xff0c;也叫二叉查找树、二叉排序树&#xff0c;顾名思义&#xff0c;这种二叉树是专门用来进行数据查找的二叉树。二叉搜索树的查找其实就是二分查找。 二叉搜索树的定义&#xff1a; 二叉搜索树可以为空如果二叉搜索树不为空&#xff0c;那么每个…

Design Compiler工具学习笔记(7)

目录 引言 背景知识 多时钟设计 DC 输出文件分析 实际操作 设计源码 综合脚本 综合网表 SDF文件 SDC文件 REPORT文件 引言 本篇继续学习 DC的基本使用。本篇主要学习 DC 综合之后的效果分析&#xff0c;多同步时钟设计以及 DC 综合完成之后的各种输出文件。 前文链…

微信小程序开发基础(03视图与逻辑)

学习目标 能够知道如何实现页面之间的导航跳转 能够知道如何实现下拉刷新效果 能够知道如何实现上拉加载更多效果 能够知道小程序中常用的生命周期函数 页面导航 1. 什么是页面导航 页面导航指的是页面之间的相互跳转。例如&#xff0c;浏览器中实现页面导航的方式有如下两…

关于环境保护html网页设计完整版,5个以环境为主题的网页设计与实现

&#x1f380; 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

《剑指 Offer 》—50. 第一个只出现一次的字符

《剑指 Offer 》—50. 第一个只出现一次的字符 一、题目内容 原题连接&#xff1a;https://leetcode.cn/problems/di-yi-ge-zhi-chu-xian-yi-ci-de-zi-fu-lcof/description/ 题目&#xff1a;在字符串 s 中找出第一个只出现一次的字符。如果没有&#xff0c;返回一个单空格。…

【专栏】核心篇06| Redis 存储高可用背后的模式

关注公众号 【离心计划】呀&#xff0c;一起逃离地球表面 Redis专栏合集 【专栏】01| Redis夜的第一章 【专栏】基础篇02| Redis 旁路缓存的价值 【专栏】基础篇03| Redis 花样的数据结构 【专栏】基础篇04| Redis 该怎么保证数据不丢失&#xff08;上&#xff09; 【专栏…

RabbitMQ------发布确认高级(消息回调、回退、备份交换机)(八)

RabbitMQ------发布确认高级&#xff08;八&#xff09; 可能由于某些意外情况&#xff0c;导致RabbitMQ重启&#xff0c;在RabbitMQ重启过程中&#xff0c;生产者投递消息失败&#xff0c;导致消息丢失。 如果才能够保证RabbitMQ的消息可靠性呢&#xff1f; 可能出现两种问题…

大数据毕设选题 - 深度学习火焰识别检测系统(python YOLO)

文章目录0 前言1 基于YOLO的火焰检测与识别2 课题背景3 卷积神经网络3.1 卷积层3.2 池化层3.3 激活函数&#xff1a;3.4 全连接层3.5 使用tensorflow中keras模块实现卷积神经网络4 YOLOV54.1 网络架构图4.2 输入端4.3 基准网络4.4 Neck网络4.5 Head输出层5 数据集准备5.1 数据标…

CSRF漏洞简介

今天继续给大家介绍渗透测试相关知识&#xff0c;本文主要内容是CSRF漏洞原理、产生与危害。 免责声明&#xff1a; 本文所介绍的内容仅做学习交流使用&#xff0c;严禁利用文中技术进行非法行为&#xff0c;否则造成一切严重后果自负&#xff01; 再次强调&#xff1a;严禁对未…

Maven——分模块开发与设计(重点)

目录 一、模块拆分 1.1 模块拆分思想 1.2 pojo模块拆分 1.3 dao模块拆分 1.4 service模块拆分 1.5 controller模块拆分 二、 聚合——模块聚合 三、继承——模块继承 一、模块拆分 1.1 模块拆分思想 左侧&#xff1a;我们从前的架构&#xff0c;一个人独立做的所有工作文件…

shell脚本的条件判断1:字符串和数字和比较

前言 写脚本时&#xff0c;为了让脚本更接近人类思考问题的方式&#xff0c;可以对各种情况进行判断。例如&#xff0c;经常需要判断某些条件是否成立&#xff0c;如果条件成立该如何处理&#xff0c;如果条件不成立又该如何处理&#xff0c;这些都可以通过Shell脚本的if语句结…

大数据_什么是数据中台?

目录 一、数据中台的定义 二、数据中台必备的是个核心能力 三、数据中台VS业务中台 四、数据中台VS数据仓库 五、数据中台VS现有信息架构 六、数据中台的业务价值与技术价值 一、数据中台的定义 数据中台是一套可持续“让企业的数据用起来”的机制&#xff0c;是一种战略…

vm的生命周期钩子

vm的生命周期钩子&#xff08;共11个&#xff09;&#xff1a; 前8个&#xff1a; 将要创建>调用beforeCreate函数 创建完毕>调用created函数 将要挂载>调用beforeMount函数 &#xff08;重要&#xff09;挂载完毕>调用mounted函数>【重要钩子】 将要更新…

用户画像洞察分类模型 - 前端页面展示

文章目录一、前端与数据智能二、 体验优化需求场景跳失预测交互偏好智能 UI三、 关键技术鲸幂 UICook&#xff08;智能UI&#xff09;DataCookPipCookPipeline四、 体验优化实践数据智能实践的一般流程数据采集数据分析 -如何对数据进行分析处理并得出结论数据应用 - 分析结论如…