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

news2024/10/7 10:21:13

一、实验目的:

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

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

二、实验内容:

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;
}

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

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

相关文章

解决:Git报错same change IDs

当使用git review的时候&#xff0c;review失败&#xff0c;报错multi commit …same change ids。。 错误&#xff1a; same Change-Id in multiple changes 意思是说&#xff0c;有多个commit记录的change ids是相同的&#xff0c;这change id概念出现在gerrit&#xff0…

将VS工程转为pro工程及VS安装Qt插件后没有create basic .pro file菜单问题解决

目录 1. 前言 2. VS工程转为pro工程 3. 没有create basic .pro file菜单 1. 前言 很多小伙伴包括本人&#xff0c;如果是在Windows下开发Qt程序&#xff0c;偏好用Visual Studio外加装个Qt插件进行Qt开发&#xff0c;毕竟Visual Studio确实是功能强大的IDE&#xff0c;但有时…

国际阿里云:Windows系统ECS实例中CPU使用率较高问题的排查及解决方案!!

问题现象 Windows系统ECS实例中CPU使用率较高&#xff0c;即CPU使用率≥80%。 问题原因 CPU使用率较高可能有以下原因。 ECS实例遭到病毒木马入侵。 ECS实例中第三方杀毒软件运行。 ECS实例中应用程序异常、驱动异常、高I/O使用率或高中断处理的应用程序。 解决方案 步骤…

OAuth2.0和1.0的区别

OAuth2.0的最大改变就是不需要临时token了&#xff0c;直接authorize生成授权code&#xff0c;用code就可以换取accesstoken了&#xff0c;同时accesstoken加入过期&#xff0c;刷新机制&#xff0c;为了安全&#xff0c;要求第三方的授权接口必须是https的。OAuth2.0不能向下兼…

基础课27——人工智能训练师人才画像

1.什么是人工智能训练师 根据《人工智能训练师》国家职业技能标准&#xff08;2021年版&#xff09;&#xff0c;人工智能训练师是指“使用智能训练软件&#xff0c;在人工智能产品使用过程中进行数据库管理、算法参数设置、人机交互设计、性能测试跟踪及其他辅助作业的人员”…

社区治理进化史!拓世法宝化身“虚拟社工”,点亮智能社区的每一个角落

时光流转、技术猛进&#xff0c;社区不再只是在制度层面作为城市治理的最小单元&#xff0c;更是在民生层面成为政府联系、服务群众的“神经末梢”。城市的脚步越来越匆忙&#xff0c;人们对于社区的服务期待也愈发高涨。面对日益复杂的社区治理和服务需求&#xff0c;我们迫切…

建设大型综合运维平台,对接集成多厂商网管系统

当前&#xff0c;云计算、大数据、人工智能等IT技术迅猛发展&#xff0c;企业的信息化步入了一个崭新的时代&#xff0c;企业规模不断壮大&#xff0c;业务不断拓展&#xff0c;企业信息化依赖的网络结构和IT技术越来越复杂。因建设时期等原因&#xff0c;企业网络中分布着不同…

Springboot SpringCloudAlibaba Nacos 项目搭建

依赖版本&#xff1a; spring-boot&#xff1a;2.3.12.RELEASE spring-cloud-alibaba&#xff1a;2.2.7.RELEASE spring-cloud&#xff1a;Hoxton.SR12 nacos&#xff1a;2.0.3 1.部署搭建Nacos注册中心 Linux Nacos 快速启动_nacos linux快速启动-CSDN博客 2.构建项目 源码地…

美国突传两件大事!大饼单日涨跌2500美元,以太走出“独立行情”!

​ 受「比特币ETF正式进入批准窗口期」利好消息刺激&#xff0c;比特币持续攀升&#xff0c;并最终于9日晚间23点突破38000美元关口&#xff0c;创下自2022年5月22日以来最高水平。 据了解&#xff0c;彭博ETF分析师James Seyffart发文称&#xff0c;比特币ETF正式进入批准窗…

mysql的sql_mode参数

msql修改了这个参数&#xff0c;首先mysql需要重新才能生效&#xff0c;还有就是java连接的springboot项目也需要重新启动。之前是遇到了下面的这个报错。只需要把sql_mode设置为空&#xff0c;重启mysql和服务就行 报错 In aggregated query without GROUP BY, expression #1…

网络安全(黑客)自学笔记1.0

前言 今天给大家分享一下&#xff0c;很多人上来就说想学习黑客&#xff0c;但是连方向都没搞清楚就开始学习&#xff0c;最终也只是会无疾而终&#xff01;黑客是一个大的概念&#xff0c;里面包含了许多方向&#xff0c;不同的方向需要学习的内容也不一样。 算上从学校开始学…

NSS [HUBUCTF 2022 新生赛]checkin

NSS [HUBUCTF 2022 新生赛]checkin 判断条件是if ($data_unserialize[username]$username&&$data_unserialize[password]$password)&#xff0c;满足则给我们flag。正常思路来说&#xff0c;我们要使序列化传入的username和password等于代码中的两个同名变量&#xff0…

高斯分布-最大似然估计公式白板推导

由上述推导得出结论&#xff1a; μ M L E 1 N ∑ i 1 N x i \mu_{MLE}\frac{1}{N}\sum\limits _{i1}^{N}x_{i} μMLE​N1​i1∑N​xi​ σ ^ 2 1 N − 1 ∑ i 1 N ( x i − μ ) 2 \hat{\sigma}^{2}\frac{1}{N-1}\sum\limits _{i1}^{N}(x_{i}-\mu)^{2} σ^2N−11​i1∑N…

数字滤波器分析---零极点分析

数字滤波器分析---零极点分析 zplane 函数绘制线性系统的极点和零点。 例如&#xff0c;在 -1/2 处为零且在 0.9e−j2π0.3 和 0.9ej2π0.3 处有一对复极点的简单滤波器为 zer -0.5; pol 0.9*exp(j*2*pi*[-0.3 0.3]); 要查看该滤波器的零极点图&#xff0c;您可以使用 z…

需求调研,是做好商业智能BI的第一步

商业智能BI&#xff0c;一个高大上的名字&#xff0c;一直被很多人认为是企业信息化中的“面子工程”。美其名曰“可视化大屏”&#xff0c;什么经营驾驶舱&#xff0c;什么管理仪表盘&#xff0c;都是花里胡哨的东西&#xff0c;老板不会看&#xff0c;企业不会用&#xff0c;…

Python 解决tkinter的Menu菜单command参数与bind方法共用触发事件

用普通函数作为媒介&#xff0c;使用event_generate()方法模拟触发bind()事件来创建一个模拟的event对象&#xff0c;并将其传递给绑定的事件处理函数。 运行结果 示例代码 import tkinter as tk# 菜单事件 def menuEvent(event):print(event.x, event.y)label.config(textf鼠…

Windows系统Python语言环境下通过SDK进行动作捕捉数据传输

NOKOV度量动作捕捉系统可以与市面上主流的操作系统和编程语言实现通信。可以在Windows系统Python语言环境下通过SDK进行动作捕捉数据传输。 一、形影软件设置 1、切换到后处理模式 2、加载一段刚体数据 3、打开软件设置 4、将网卡地址选择为10.1.1.198 5、勾选上"使用SD…

java项目之戒烟网站(ssm+vue)

项目简介 戒烟网站实现了以下功能&#xff1a; 用户可以对首页&#xff0c;用户分享&#xff0c;论坛交流&#xff0c;公告文章&#xff0c;个人中心&#xff0c;后台管理等功能进行操作。 管理员可以对网站所有功能进行管理&#xff0c;包括管理用户的基本信息。 &#x1f4…

快速开发一个简单实用的MES系统?

题主在一个光伏组件工厂做生产管理&#xff0c;但工厂竟然没有MES系统&#xff0c;于是想自己开发一个简单的MES系统。那么我们来看看题主对于开发MES系统的要求—— 对系统&#xff1a;每一个产品都有一个条形码&#xff0c;希望系统可以追踪生产计划下的产品的生产状态&…

k8s ingress基础

一、ingress 简介 在k8s集群中&#xff0c;service和pod的ip为内网ip&#xff0c;仅集群内部才可以访问。如果外部应用想要直接访问集群内的服务&#xff0c;就需要把外部请求通过负载均衡转发到service上&#xff0c;然后再由kube-proxy组件将其转发给后端pod。一般service可…