操作系统第一次实验——短作业优先调度算法(SJF)

一、实验目的:

目的:了解并掌握作业调度的功能,熟悉并掌握各种作业调度算法。

任务:模拟实现先来先服务或者短作业优先调度算法。

二、实验内容:

1、实验内容

模拟实现SJF调度。

设置作业体:作业名,作业的到达时间,服务时间,作业状态(W——等待,R——运行,F——完成),作业间的链接指针;

作业初始化:由用户输入作业名、服务时间、到达时间进行初始化,同时,初始化作业的状态为W。

显示函数:在作业调度前、调度中和调度后进行显示。

排序函数:对等待状态的作业按照调度算法排序(不同的调度算法排序方式不同),注意考虑到达时间。

调度函数:每次从等待队列队首调度已到达的适合的作业执行,状态变化。当服务结束时,状态变为F。

删除函数:撤销状态为F的作业。

2、实验要求

(1)测试数据可以随即输入或从文件中读入;

(2)必须要考虑到作业的到达时间;

(3)最终能够计算每一个作业的周转时间、带权周转时间。

三、实验代码 (C++)

1、首先定义函数体

struct process
{
    string pid;        //作业名(作业号)
    double come_time;  //到达时
    double run_time;   //运行时
    double begin_time; //开始时
    double over_time;  //完成时
    double round_time; //周转时
    double avg_time;   //带权周转时
    double HRR;        //响应比
    char state;		   // 状态 
	double need_time;  // 所剩余需要服务的时间 
} pc[MAXSIZE];         //作业数

2、定义完函数体后,对进程进行排序算法。

bool CmpByComeTime(process p1, process p2) // 按到达时间正序排序
{
    return p1.come_time < p2.come_time;
}
bool CmpByPid(process p1, process p2) // 按id号正序排序
{
    return p1.pid < p2.pid;
}
bool CmpByRunTime(process p1, process p2) // 按运行时长正序排序
{
    return p1.run_time == p2.run_time ? p1.come_time < p2.come_time : p1.run_time < p2.run_time;
}

 3、写完排序函数后,计算进程的开始时间与到达时间

void get_beginAndOver_time() // 计算作业的开始时间与完成时间
{
    for (int i = 0; i < number; i++)
    {
        if (i == 0)
        {
            pc[i].begin_time = pc[i].come_time; // 第一个作业的开始时即为其到达时
        }
        else
        {
            pc[i].begin_time = pc[i - 1].over_time; // 否则后一作业的开始时为前一个作业的完成时
        }
        pc[i].over_time = pc[i].begin_time + pc[i].run_time; // 作业完成时 = 开始时间 + 运行时间
    }
}

4、进行对周转时间,带权周转时间的计算

  1. 完成时间=开始时间+服务时间
  2. 周转时间=完成时间-到达时间
  3. 带权周转时间=周转时间/服务时间
void get_roundAndAvg_time() // 计算作业的周转时间与带权周转时间
{
    for (int i = 0; i < number; ++i)
    {
        pc[i].round_time = pc[i].over_time - pc[i].come_time;     // 周转时 = 完成时间 - 到达时间
        pc[i].avg_time = pc[i].round_time * 1.0 / pc[i].run_time; // 平均周转时 = 周转时间 / 运行时间
    }
}

 5、计算完成后,写SJF的函数体

void SJF() // SJF(short job first):根据作业的运行时间从小到大依次执行
{
    sort(pc, pc + number, CmpByComeTime);    // 先按到达时排序
    sort(pc + 1, pc + number, CmpByRunTime); // 再按运行时排序
    get_beginAndOver_time();
    get_roundAndAvg_time();
}

四、实验结果 

如图

 

五、完整代码

#include <iostream>
#include <algorithm>
using namespace std;
#define MAXSIZE 5 // 作业数
int number; // 用户输入的进程数量
struct process
{
    string pid;        //作业名(作业号)
    double come_time;  //到达时
    double run_time;   //运行时
    double begin_time; //开始时
    double over_time;  //完成时
    double round_time; //周转时
    double avg_time;   //带权周转时
    double HRR;        //响应比
    char state;		   // 状态 
	double need_time;  // 所剩余需要服务的时间 
} pc[MAXSIZE];         //作业数
bool CmpByComeTime(process p1, process p2) // 按到达时间正序排序
{
    return p1.come_time < p2.come_time;
}
bool CmpByPid(process p1, process p2) // 按id号正序排序
{
    return p1.pid < p2.pid;
}
bool CmpByRunTime(process p1, process p2) // 按运行时长正序排序
{
    return p1.run_time == p2.run_time ? p1.come_time < p2.come_time : p1.run_time < p2.run_time;
}

void get_beginAndOver_time() // 计算作业的开始时间与完成时间
{
    for (int i = 0; i < number; i++)
    {
        if (i == 0)
        {
            pc[i].begin_time = pc[i].come_time; // 第一个作业的开始时即为其到达时
        }
        else
        {
            pc[i].begin_time = pc[i - 1].over_time; // 否则后一作业的开始时为前一个作业的完成时
        }
        pc[i].over_time = pc[i].begin_time + pc[i].run_time; // 作业完成时 = 开始时间 + 运行时间
    }
}
void get_roundAndAvg_time() // 计算作业的周转时间与带权周转时间
{
    for (int i = 0; i < number; ++i)
    {
        pc[i].round_time = pc[i].over_time - pc[i].come_time;     // 周转时 = 完成时间 - 到达时间
        pc[i].avg_time = pc[i].round_time * 1.0 / pc[i].run_time; // 平均周转时 = 周转时间 / 运行时间
    }
}

void SJF() // SJF(short job first):根据作业的运行时间从小到大依次执行
{
    sort(pc, pc + number, CmpByComeTime);    // 先按到达时排序
    sort(pc + 1, pc + number, CmpByRunTime); // 再按运行时排序
    get_beginAndOver_time();
    get_roundAndAvg_time();
}

void qianprint()
{
	cout << endl;
    cout << "作业名" << '\t' << "到达时" << '\t' << "运行时" << '\t'
	         << "开始时" << '\t' << "完成时" << '\t' << "状态" << '\t'
	         << endl;
    for (int i = 0; i < number; ++i)
    {
        /* code */
//		sum_round_time = pc[i].over_time;
		pc[i].state='W';
	}
    for (int i = 0; i < number; ++i)
    {

        cout << pc[i].pid << '\t' << pc[i].come_time << '\t'
	             << pc[i].run_time << '\t' << pc[i].begin_time << '\t'
	             << pc[i].over_time << '\t' << pc[i].state<<'\t' << endl;
    }
}
void printProcess() // 打印作业的过程 
{
	double atime=1;
	double sum_round_time = 0.0;
	for (int i = 0; i < number; ++i)
    {
        /* code */
		sum_round_time = pc[i].over_time;
		pc[i].state='W';
	}
//	cout<<sum_round_time<<endl;
	for (atime;atime<=sum_round_time;++atime){
		cout<<'\t'<<endl; 
		cout << "第"<<atime<<"个时间周期" <<'\t'<< endl;
		cout << endl;
	    cout << "作业名" << '\t' << "到达时" << '\t' << "运行时" << '\t'
	         << "开始时" << '\t' << "需要时" << '\t' << "状态" << '\t'
	         << endl;
	    for (int i = 0; i < atime&&i<number; ++i)
    	{
    		for (int j = 0; j < number; ++j)
    		{
    			
		        if (atime==pc[j].come_time&&(pc[j-1].state=='\0'||pc[j-1].state=='F'))
				{
					pc[j].state='R';
				}
				else if(atime>=pc[j].over_time){
					pc[j].state='F';
					pc[j+1].state='R';
				}
			}
		pc[i].need_time=pc[i].over_time-atime;
		if(pc[i].need_time>=0)
		{
			pc[i].need_time=pc[i].need_time;
			
		}
		else
		{
			pc[i].need_time=0;
		}
		if(atime>=pc[i].come_time){
			 cout << pc[i].pid << '\t' << pc[i].come_time << '\t'
	             << pc[i].run_time << '\t' << pc[i].begin_time << '\t'
	             << pc[i].need_time << '\t' << pc[i].state<<'\t' << endl;
		} 
    	}     
    }
        
    
}

void printResult() // 打印输出作业的各个时间值
{
    cout << "执行顺序:"; // << endl
    for (int i = 0; i < number; ++i)
    {
        /* code */
        cout << pc[i].pid<< " ";
        
    }
    cout << endl;
    cout << "作业名" << '\t' << "到达时" << '\t' << "运行时" << '\t'
         << "开始时" << '\t' << "完成时" << '\t' << "周转时" << '\t'
         << "带权周转时" << '\t' << endl;
    sort(pc, pc + number, CmpByPid);
    double sum_round_time = 0.0;
    double avg_sum_round_time = 0.0; // 平均周转时间
    double sum_avg_time = 0.0;
    double avg_sum_avg_time = 0.0; // 平均带权周转时间
    for (int i = 0; i < number; ++i)
    {
        sum_round_time += pc[i].round_time;
        sum_avg_time += pc[i].avg_time;
        cout << pc[i].pid << '\t' << pc[i].come_time << '\t'
             << pc[i].run_time << '\t' << pc[i].begin_time << '\t'
             << pc[i].over_time << '\t' << pc[i].round_time << '\t'
             << pc[i].avg_time << endl;
    }
    avg_sum_round_time = sum_round_time * 1.0 / number;
    avg_sum_avg_time = sum_avg_time * 1.0 / number;
    cout << "平均周转时间: " << avg_sum_round_time << endl
         << "平均带权周转时间: " << avg_sum_avg_time << endl;
}
int main() // 入口函数
{
	int atime=1;
    cout << "请输入进程个数:";
    cin >> number;
    cout << endl;
    cout << "请分别输入进程的名称、到达时间、服务时间:" << endl;
    for (int i = 0; i < number; i++)
    {
        cin >> pc[i].pid >> pc[i].come_time >> pc[i].run_time;
    }
    cout << endl;
    SJF();
    cout << "运行前的任务:" <<'\t'<< endl;
    qianprint();
    cout << "运行中的任务调度过程:" <<'\t'<< endl;
    printProcess();
    cout << "the results of SJF are:" << endl;
	printResult();
    
    system("pause");
    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

关于mac下pycharm旧版本没删除的情况下新版本2023安装之后闪退

先说结论&#xff0c;我用的app cleaner 重新删除的pycharm &#xff0c;再重新安装即可。在此记录一下 之前安装的旧版的2020的pycharm&#xff0c;因为装不了新的插件&#xff0c;没办法就升级了。新装2023打开之后闪退&#xff0c;重启系统也不行&#xff0c;怀疑是一起破解…

类图复习:类图简单介绍

入职新公司在看新项目的代码&#xff0c;所以借助类图梳理各个类之间的关系&#xff0c;奈何知识已经还给了老师&#xff0c;不得不重新学习下类图的相关知识&#xff0c;此处将相关内容记录下方便后续使用。 文章目录 类图语法类与类的关系画类图 类图语法 语法描述public-pr…

C语言--typedef的使用

前言 在C语言中使用结构体时必须加上struct这个关键字,那有没有办法省略这个呢?要想达到这个目的就 需要用到关键字typedef,顾名思义”类型定义”。 typedef 数据类型 新的别名; 它是用来操作数据类型。其主要作用有两个: 1.给一个较长较复杂的类型取一个简单的别名。 2.给类…

MySQL其他集群类型介绍

常用的/常见的Mysql集群方案 1.MySQL Replication2.MySQL Fabric3.MySQL NDB Cluster4.MGR&#xff08;MySQL Group Replication&#xff09;5.心跳检测SAN共享存储&#xff08;heartbeat SAN&#xff09;6.心跳检测DRBD磁盘复制&#xff08;heartbeat DRBD&#xff09;7.MMM…

大桌子想传大文件

受高手指导说服务器想传大点的文件&#xff0c;得把两个地方改改 先是这里 然后这里也要改 哦。对了&#xff0c;改完之后要重启服务器。别忘了。

网络爬虫代理ip有什么好处?爬虫工作使用代理IP有哪些优势?

在爬虫工作中&#xff0c;使用代理IP有很多好处&#xff0c;可以帮助爬虫程序更加高效地完成任务。以下是使用代理IP的几个优势&#xff1a; 1. 增加匿名性 使用代理IP可以隐藏爬虫程序的真正IP地址&#xff0c;增加匿名性&#xff0c;避免被目标网站封禁。通过代理IP&#xff…

【ElasticSearch系列-07】ES的开发场景和索引分片的设置及优化

ElasticSearch系列整体栏目 内容链接地址【一】ElasticSearch下载和安装https://zhenghuisheng.blog.csdn.net/article/details/129260827【二】ElasticSearch概念和基本操作https://blog.csdn.net/zhenghuishengq/article/details/134121631【三】ElasticSearch的高级查询Quer…

高德地图 web js端 出现 INVALID_USER_SCODE 10008 MD5安全码未通过验证

图片意思就是在引入 高德js和css 链接前 引入 <script type"text/javascript">window._AMapSecurityConfig {securityJsCode:您申请的安全密钥,} </script> 到这里就完美结束了

【JavaEE初阶】 TCP三次握手四次挥手(超详细版)

文章目录 &#x1f334;三次握手四次挥手总览&#x1f6eb;三次握手&#xff08;建立连接&#xff09;&#x1f6a9;为什么要三次握手&#x1f4cc;解决彼此双发彼此认同的问题&#x1f4cc;验证双方的接听发送能力是否正常 &#x1f6a9;建立连接阶段涉及到的两个重要状态: &a…

blender动画制作软件拓扑全流程

拓扑在三维动画制作中至关重要&#xff0c;原因如下&#xff1a; 1. 动画变形&#xff1a; 自然形变&#xff1a; 良好的拓扑结构能够支持角色或物体在动画中的自然形变&#xff0c;例如关节弯曲、肌肉收缩等。流畅运动&#xff1a; 适当的拓扑有助于保持模型表面的平滑性&…

Linux友人帐之网络编程基础FTP服务器

一、概述 1.1FTP基本概念 FTP&#xff08;File Transfer Protocol&#xff09;是一种用于文件传输的标准协议。FTP服务是一种能够让用户通过FTP协议在本地计算机和远程服务器之间进行文件传输的服务。FTP服务可以允许用户上传或下载文件&#xff0c;也可以进行目录浏览、文件删…

Windows安装Docker(无网)

Windows安装Docker&#xff08;无网&#xff09; window无网安装Docker 1. 开启虚拟化功能 1. 开启window的虚拟化功能 方式一&#xff1a;直接在window的搜索框搜索 “启用或关闭windows功能”&#xff0c;就可以快捷进入【启用或关闭windows功能】页面 方式二&#xff1…

【MySQL】想不想知道数据库到底是啥?想了就进来看看

数据库是什么 前言正式开始连接mysql理解mysql第一层理解第二层理解第三层理解 小问题见见猪跑show databases;create database xxx;create table xxx; 主流数据库mysql架构SQL语句的种类存储引擎 前言 你手上有没有MySQL&#xff1f;有了最好&#xff0c;没有的话建议下一个&…

2022美亚杯团队赛

2022美亚杯团体赛 - XDforensics-Wiki 2022 美亚杯 团体赛AGC部分资格赛服务器部分 所有服务器部分解题思路_2022美亚杯团体赛复盘-CSDN博客 目录 AGC 1 2 Media Sever挂载 3 ssh登入的看法 PTS 4 5 ssh日志 6 7 查看docker列表 8 查看docker运行 9 建立网站…

solidworks对电脑要求高吗?2023solidworks配置要求

solidworks对电脑要求高吗&#xff1f;SolidWorks是一款功能强大的三维CAD软件&#xff0c;对电脑配置有一定的要求。一般来说&#xff0c;运行SolidWorks需要的电脑配置包括较高的处理器性能、足够的内存和存储空间&#xff0c;以及一块性能良好的显卡。此外&#xff0c;对于大…

Leetcode_3:无重复字符的最长子串

题目描述&#xff1a; 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 示例 1: 输入: s "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc"&#xff0c;所以其长度为 3。 示例 2: 输入: s "bbbbb"…

记一次上位机软件线程泄露的分析及解决

上位机软件在客户现场隔一段时间说操作了没反应&#xff0c;但是上位机又没死&#xff0c;出现了一些奇怪现象&#xff1a; 左上角的时间不走了&#xff08;本来是1s运行一次&#xff09;使用任务管理器查看&#xff0c;内存占用1.5G,线程有3000多个&#xff0c;正常情况下&am…

将 ONLYOFFICE 文档编辑器与 С# 群件平台集成

在本文中&#xff0c;我们会向您展示 ONLYOFFICE 文档编辑器与其自有的协作平台集成。 ONLYOFFICE 是一款开源办公套件&#xff0c;包括文本文档、电子表格和演示文稿编辑器。这款套件支持用户通过文档编辑组件扩展第三方 web 应用的功能&#xff0c;可直接在应用的界面中使用。…

VMware ifconfig ip报错解决记录

1.报错 ifconfig后出现以下报错 lo: flags73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 1000 (Local Loopback) RX packets 9216 b…

Element-Ui入门教学——<el-upload>限制上传文件类型

要限制<el-upload>上传文件的类型&#xff0c;需要给组件绑定:before-upload属性。 before-upload可选参数, 上传文件之前的钩子&#xff0c;参数为上传的文件&#xff0c;若返回 false 或者 Promise 则停止上传。HTML代码 <template><el-uploadclass"uplo…