操作系统之如何使用C语言完成SFJ和SRTJ,并完成他的甘特图

news2024/11/20 18:29:59

目录

前言

SFJ

SRTJ

结束语


前言

不知不觉已经写博客一个月了,前段时间因为学业上的一些原因咕咕咕了,今天我又回来了。今天我给大家带来的是C语言代码完成的SFJ和SRTJ,并且带大家描述他的甘特图。如果有对SFJ和SRTJ不了解的小伙伴可以翻博主曾经的文章,那里有详细的讲解。


SFJ

讲解

我们在代码中,需要传入进程的编号process、到达时间arrive、服务时间serve、进程数量pro,我这里还传入一个参数choice代表选择默认数据还是自行输入的数据,小伙伴们可以根据实际情况进行删减。

SFJ的实现非常简单,只需要在每次有进程到达时,判断当前各进程在就绪队列中进程的服务时间长短并进行排序即可,然后依次输出就好。

我在完成代码时,使用了冒泡排序,其实可以用其他排序,时间复杂度更低,效率更高,因为完成时我们用到的数据量不大,所以就用了冒泡,实现起来比较简单(doge)。

其中第一个if是用来判断到达时间的先后,对他们进入就绪队列的前后进行判断。第二个if是对两个同时进入就绪队列的进程,用他们的服务时间来判断谁先谁后,达到SFJ的思想。

代码

下面上代码

void SJF(int process[],int arrive[],int serve[],int pro,int choice){
    double wait = 0.0;//计算平均等待时间
    printf("当前SJF的数据如下:\n进程编号:\t\t到达时间:\t\t服务时间:\t\t\n");
    for(int i = 0;i<pro;i++){
        printf("P%d\t\t\t%d\t\t\t%d\t\t\t\n",process[i],arrive[i],serve[i]);
    }
    printf("------------------------------------------------------------------------------------\n");
    for(int i = 0;i<pro;i++){
        for(int j = 0;j<pro - i - 1;j++){
            int temp;
            if(arrive[j]>arrive[j+1]){
                temp = arrive[j+1];
                arrive[j+1] = arrive[j];
                arrive[j] = temp;
                temp = process[j+1];
                process[j+1] = process[j];
                process[j] = temp;
                temp = serve[j+1];
                serve[j+1] = serve[j];
                serve[j] = temp;
            }
            if(arrive[j]==arrive[j+1]){
                if(serve[j]>serve[j+1]){
                    temp = arrive[j+1];
                    arrive[j+1] = arrive[j];
                    arrive[j] = temp;
                    temp = process[j+1];
                    process[j+1] = process[j];
                    process[j] = temp;
                    temp = serve[j+1];
                    serve[j+1] = serve[j];
                    serve[j] = temp;
                }
            }
        }
    }
    int end = 0,start = 0;
    printf("\n甘特图描述如下:\n");
    for(int i = 0;i<pro;i++){
        //从当前进程开始,如果进程已经到达,则比较服务时间长短,服务时间短的先
        for(int j = i;j<pro-1;j++){
            if(arrive[j] <= end){
                for(int kk = i;kk < pro;kk++){
                    //进程还没到达,就退出比较
                    if(arrive[kk] > end){
                        break;
                    }
                    if(serve[j] > serve[kk]){
                        int temp;
                        temp = arrive[j+1];
                        arrive[j+1] = arrive[j];
                        arrive[j] = temp;
                        temp = process[j+1];
                        process[j+1] = process[j];
                        process[j] = temp;
                        temp = serve[j+1];
                        serve[j+1] = serve[j];
                        serve[j] = temp;
                    }
                }
            }
        }
        end = end + serve[i];
        wait = wait + start - arrive[i];
        printf("现在运行的进程是P%d\t\t进程开始的时间是%d\t\t进程的结束时间是%d\t\t\n",process[i],start,end);
        start = end;
    }
    wait = wait / pro;
    printf("平均等待时间是:%.3lf\n",wait);
    printf("------------------------------------------------------------------------------------\n");
}

结果

接下来是结果,我们这里使用默认数据,大家也可以用自行输入的数据进行测试。


SRTJ

讲解

我们依旧使用了process、arrive、serve、pro、choice这五个参数,如果有跳着看不明白含义的小伙伴可以在SJF的开头找到解释。这里我们仍然先按照SJF的思路,把进程按照到达时间和服务时间排序。但是需要在进行算法时,注意SRTJ的重点:最短剩余时间,否则最终得出的顺序将会有错误,甘特图也会有错。

代码

接下来是大家期待的代码

void SRTJ(int process[],int arrive[],int serve[],int pro,int choice){
    double wait = 0.0;//计算平均等待时间
    printf("当前SRTJ的数据如下:\n进程编号:\t\t到达时间:\t\t服务时间:\t\t\n");
    for(int i = 0;i<pro;i++){
        printf("P%d\t\t\t%d\t\t\t%d\t\t\t\n",process[i],arrive[i],serve[i]);
    }
    printf("------------------------------------------------------------------------------------\n");
    for(int i = 0;i<pro;i++){
        for(int j = 0;j<pro - i - 1;j++){
            int temp;
            if(arrive[j]>arrive[j+1]){
                temp = arrive[j+1];
                arrive[j+1] = arrive[j];
                arrive[j] = temp;
                temp = process[j+1];
                process[j+1] = process[j];
                process[j] = temp;
                temp = serve[j+1];
                serve[j+1] = serve[j];
                serve[j] = temp;
            }
            if(arrive[j]==arrive[j+1]){
                if(serve[j]>serve[j+1]){
                    temp = arrive[j+1];
                    arrive[j+1] = arrive[j];
                    arrive[j] = temp;
                    temp = process[j+1];
                    process[j+1] = process[j];
                    process[j] = temp;
                    temp = serve[j+1];
                    serve[j+1] = serve[j];
                    serve[j] = temp;
                }
            }
        }
    }
    int n = pro;
    int currentTime = 0;
    float waitTime[pro];
    float turnaroundTime[pro];
    int remainingTime[pro];
    int completed = 0;
    int startTime[pro];
    for(int i = 0; i < n; ++i) startTime[i] = -1;
    //初始化剩余时间数组
    for(int i = 0; i < n; ++i) {
        remainingTime[i] = serve[i];
    }
    while(completed != n) {
        int next = -1,preNext[Max_Size],num = 0;
        float shortestRemaining = -1;
        for(int i = 0; i < n; ++i) {
                if(arrive[i] <= currentTime && remainingTime[i] > 0) {
                    if(startTime[i] == -1) startTime[i] = currentTime; // 进程首次执行时记录开始时间
                    if(shortestRemaining == -1 || remainingTime[i] < shortestRemaining) {
                        shortestRemaining = remainingTime[i];
                        next = i;
                    }
                }
        }
        preNext[num] = next;
        num++;
        if (next != -1) {
            remainingTime[next]--;
            currentTime++;
            if(startTime[next] != -1) {
                printf("现在运行的进程是P%d,开始时间是%d,结束时间是:%d\n", process[next], currentTime-1,currentTime);
            }
            if(remainingTime[next] == 0) {
                waitTime[next] = currentTime - arrive[next] - serve[next];
                turnaroundTime[next] = currentTime - arrive[next];
                completed++;
            }
        }
        else {
            // 没有进程可调度时,推进时间到下一个进程的到达时间
            for(next = 0; next < n; ++next) {
                if(arrive[next] > currentTime) {
                    currentTime = arrive[next];
                    break;
                }
            }
            if(next == n) break;
        }
    }
    for(int i = 0;i<pro;i++){
        wait = wait + waitTime[i];
    }
    wait = wait / pro;
    printf("平均等待时间是:%.3lf\n",wait);
    printf("------------------------------------------------------------------------------------\n");
}

结果


结束语

今天对SFJ和SRTJ的讲解就到这里了,希望对大家有帮助。如果对大家有帮助,希望大家可以给我一个点赞、关注、收藏,这对我很重要,谢谢大家!

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

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

相关文章

windows anaconda 安装 Labelme

安装 # 创建环境 conda create -n labelme python3.6 #激活环境 conda activate labelme # 安装依赖 conda install pyqt conda install pillow # 安装labelme conda install labelme3.16.2 # 启动labelme labelme右键选择标注类型&#xff0c;从上到下为多边形&#xff08;常…

超声波清洗机哪个牌子好用点?四大卓越臻品不容错过!

选购超声波清洗机能为日常生活提供非常多的便利&#xff01;比如像是戴眼镜或者是有婴儿的家庭&#xff0c;使用超声波清洗机不仅能够帮助清洗需要清洗的物品&#xff0c;同时更能保证物品健康清洁&#xff0c;对清洗的物品进行杀菌灭菌&#xff01;相对于比较费时间并且容易损…

eclipse宝刀未老

Theia 是一个高度可定制的、开源的、基于 Web 的集成开发环境&#xff08;IDE&#xff09;框架。它由 Eclipse Foundation 主导&#xff0c;旨在为云和本地环境提供现代化的、全功能的 IDE 解决方案。Theia 的核心目标是提供一个灵活的平台&#xff0c;开发者可以根据自己的需求…

2005-2022年款福特福克斯维修手册和电路图线路图接线图资料更新

经过整理&#xff0c;2005-2022年款福特福克斯全系列已经更新至汽修帮手资料库内&#xff0c;覆盖市面上99%车型&#xff0c;包括维修手册、电路图、新车特征、车身钣金维修数据、全车拆装、扭力、发动机大修、发动机正时、保养、电路图、针脚定义、模块传感器、保险丝盒图解对…

MaxWell实时监控Mysql并把数据写入到Kafka主题中

配置mysql 启用MySQL Binlog MySQL服务器的Binlog默认是未开启的&#xff0c;如需进行同步&#xff0c;需要先进行开启 修改MySQL配置文件/etc/my.cnf sudo vim/etc/my.cof 增加如下配置 注&#xff1a;MySQL Binlog模式 Statement-based&#xff1a;基于语句&#xff0c;…

定制化物联网设备:开启智能生活新篇章

随着科技的进步&#xff0c;物联网&#xff08;IoT&#xff09;已成为我们日常生活和工作中不可或缺的一部分。从智能家居到工业自动化&#xff0c;物联网设备以其独特的功能和特性&#xff0c;极大地提高了我们的生活质量和工作效率。然而&#xff0c;在众多的物联网设备中&am…

【深度解析】1688货源拿货价比拼多多贵?为何商家仍选1688

对电商卖家来说&#xff0c;首先需要解决的问题就是货源。 虽然知道1688是个大型综合性的货源平台&#xff0c;但很多卖家还是觉得1688上面的货源很贵&#xff0c;甚至在平台严查无货源的背景下&#xff0c;还是坚持从1688拿货。那么为什么有些拼多多的商品会比1688还便宜呢&a…

基于大型语言模型的全双工语音对话方案

摘要解读 我们提出了一种能够以全双工方式运行的生成性对话系统&#xff0c;实现了无缝互动。该系统基于一个精心调整的大型语言模型&#xff08;LLM&#xff09;&#xff0c;使其能够感知模块、运动功能模块以及一个具有两种状态&#xff08;称为神经有限状态机&#xff0c;n…

Linux系统编程——进程信号

目录 一&#xff0c;信号预备 1.1 生活中的信号 1.2 技术应用中的信号 1.3 signal函数捕捉信号 1.3 信号的发送与记录 1.4 信号的常见处理方式 二&#xff0c;信号的产生 2.1 核心转储 2.1.1 环境配置 2.1.2 利用core文件进行调试 2.1.3 core dump标志 2.2 通过系统…

【Python机器学习实战】 | 基于空气质量监测数据,采用多层神经网络预测PM2.5浓度

&#x1f3a9; 欢迎来到技术探索的奇幻世界&#x1f468;‍&#x1f4bb; &#x1f4dc; 个人主页&#xff1a;一伦明悦-CSDN博客 ✍&#x1f3fb; 作者简介&#xff1a; C软件开发、Python机器学习爱好者 &#x1f5e3;️ 互动与支持&#xff1a;&#x1f4ac;评论 &…

【漏洞复现】海康威视 综合安防管理平台软件 center_api_files 任意文件上传漏洞

免责声明&#xff1a; 本文内容旨在提供有关特定漏洞或安全漏洞的信息&#xff0c;以帮助用户更好地了解可能存在的风险。公布此类信息的目的在于促进网络安全意识和技术进步&#xff0c;并非出于任何恶意目的。阅读者应该明白&#xff0c;在利用本文提到的漏洞信息或进行相关测…

Navicat 重装 查找 保存的查询sql文件

背景&#xff1a;Navicat 一个收费的软件&#xff0c;存在的最大缺点就是收费&#xff0c;所以我们为了优化它会遇到卸载重装这些复杂的过程&#xff0c;但是我们保存的查询sql会跟随卸载Navicat而删除&#xff0c;为了节省时间省去不必要的麻烦&#xff0c;我们可以查到我们保…

YOLOv10改进 | 注意力篇 | YOLOv10引入HAttention(HAT)注意力

1. HAT介绍 1.1 摘要:基于 Transformer 的方法在低级视觉任务(例如图像超分辨率)中表现出了令人印象深刻的性能。 然而,我们发现这些网络通过归因分析只能利用有限的输入信息空间范围。 这意味着 Transformer 的潜力在现有网络中仍未得到充分发挥。 为了激活更多的输入像素…

通过阿里云OOS定时升级Redis实例临时带宽

功能背景 在数据驱动的现代业务环境中&#xff0c;Redis以其卓越的性能和灵活性&#xff0c;已成为众多企业关键基础设施的重要组成部分。Redis广泛应用于处理缓存、会话管理、消息队列等多种数据密集型和响应敏感型的场景&#xff0c;对业务连续性和用户体验贡献极大。然而&a…

从入门到实战,一篇学会TS,保姆式教程

本文知识图谱分基础、进阶和实战三个部分&#xff0c;分别如下&#xff1a; image.png image.png image.png 这三份知识图谱里罗列的知识看似很多&#xff0c;实际上除了进阶部分的泛型、高级类型&#xff08;二&#xff09;和实战部分需要稍微费点脑细胞外&#xff0c;其他…

AlmaLinux 更换CN镜像地址

官方镜像列表 官方列表&#xff1a;https://mirrors.almalinux.org/CN 开头的站点&#xff0c;不同区域查询即可 一键更改镜像地址脚本 以下是更改从默认更改到阿里云地址 cat <<EOF>>/AlmaLinux_Update_repo.sh #!/bin/bash # -*- coding: utf-8 -*- # Author:…

上位机图像处理和嵌入式模块部署(h750 mcu和usb虚拟串口)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 对于mcu usb而言&#xff0c;大部分情况下&#xff0c;它和上位机之间的关系都是device的关系。一般usb&#xff0c;可以分成host和device。如果mc…

windows如何运行wgcloud-agent-release

只需要右击wgcloud-agent-release.exe&#xff0c;用管理员身份&#xff0c;启动就好啦 你也可以双击regAgentService.bat&#xff0c;将agent注册为系统服务&#xff0c;然后在系统服务里面启动wgcloud-agent-release服务&#xff0c;这样可以隐藏运行窗口&#xff0c;也可以…

Vue59-全局事件总线:任意组件间通信

一、原理图 只是总结出的经验&#xff0c;不是新的API&#xff01; 二、x的要求&#xff1a; 1、保证x被所有组件看见&#xff1b; 2、x可以调用的到$on&#xff0c;才能绑定事件&#xff0c;还能调用到&#xff1a;$of&#xff0c; $emit&#xff1b; 三、x的创建&#xff…

linux系统定时任务执行脚本中断,而手动运行正常

1.问题排查 linux会给对的crontab执行者 返回信息。而这个返回的信息就是通过邮件发给执行者的&#xff0c;通过邮件可以查看你的定时任务 然后发现是在定时任务中找不到对应的命令 2. 定时任务用的什么环境 crontab默认的环境变量并没有一个固定的文件来直接定义&#xf…