模拟处理机作业调度---短作业优先调度算法

短作业优先调度原理

短作业优先调度算法是指对短作业优先调度的算法。短作业优先(SJF)的调度算法是从后备队列中选择一个或若干个估计运行时间最短的作业,将它们调入内存运行。

算法流程图

JCB 代表一个作业,JCB 的结构如下:

模拟实现

在屏幕上输出以下作业状态表:

可以通过键盘命令动态地增加作业(即增加一个 JCB 数 据结构项)。增加作业后,作业状态表内容可更新查看。

算法代码:

#include "stdafx.h"
#include<iostream>
#include <iomanip>
#include<queue>
#include<math.h>
#include<vector>
#include<algorithm>
using namespace std;

/*作业的数据结构*/
struct JCB
{
    int ID;//作业ID
    double in_time;//作业进入时间
    double ex_time;//作业执行时间
};
/*执行时间大到下排序*/
bool cmp(pair<JCB, double> first, pair<JCB, double> next)
{
    return first.second > next.second;
}
/*ID从小到大排序*/
bool cmp2(pair<JCB, double> first, pair<JCB, double> next)
{
    return first.first.ID < next.first.ID;
}
/*开始执行时间从早到晚排序*/
bool cmp3(pair<JCB, double> first, pair<JCB, double> next)
{
    return first.second < next.second;
}
/*ID从大到小排序*/
bool cmp4(pair<JCB, double> first, pair<JCB, double> next)
{
    return first.first.ID > next.first.ID;
}

/*显示作业表格*/
void ShowJobChart(vector<pair<JCB, double>>res)
{
    cout<<left;
    cout << "--------------------------------作业状态表-------------------------------------"<<endl;
    cout << setw(10) << "作业ID" << "|"<< setw(10) << "到达时间" << "|" << setw(10) << "执行时间"<<"|" << setw(10) << "开始时间" << "|" <<
        setw(10) << "完成时间" << "|" << setw(10) << "周转时间" << "|" << setw(12) << "带权周转时间" <<"|"<< endl;
    cout << "-------------------------------------------------------------------------------" << endl;
    for (auto it = res.begin();it != res.end();it++)
    {
        cout << setw(10) << it->first.ID << "|" << setw(10) <<it->first.in_time<<"|" << setw(10) << it->first.ex_time << "|" << setw(10) <<it->second<<"|"
            << setw(10) <<it->second+it->first.ex_time<<"|" << setw(10) <<
            it->second + it->first.ex_time -it->first.in_time<< "|"<< setw(12)<< (it->second + it->first.ex_time - it->first.in_time)/it->first.ex_time<<"|"<<endl;
    }
    cout << "-------------------------------------------------------------------------------" << endl;
}
/*作业调度                                       */
/*输入:待调度的作业队列jobs                     */
/*输出:调度好的作业数组res                         */
vector<pair<JCB, double>> JobScheduling(queue<JCB>jobs)
{
    JCB f_job = jobs.front();
    jobs.pop();
    //res数组用于存调度之后的结果,jcb以及对应的作业开始执行时间
    vector<pair<JCB, double>>res;
    //首先将第一个到达的工作直接加入数组
    res.push_back(make_pair(f_job, f_job.in_time));
    vector<pair<JCB, double>>job;
    double finish = f_job.in_time + f_job.ex_time;
    while (!jobs.empty())
    {
        //将到达时间在上一个执行的工作结束时间之前的作业存入job数组
        while (jobs.front().in_time <= finish)
        {
            job.push_back(make_pair(jobs.front(), jobs.front().ex_time));
            jobs.pop();
            if (jobs.empty())break;
        }
        //如果没有到达时间在上一个执行的工作结束时间之前的作业
        if (job.empty())
        {
            res.push_back(make_pair(jobs.front(), jobs.front().in_time));
            finish = jobs.front().in_time + jobs.front().ex_time;
            jobs.pop();
            continue;
        }
        //将到达时间在上一个执行的工作结束时间之前的作业按执行时间从大到小排序
        sort(job.begin(), job.end(), cmp);
        //将最短执行时间的工作存进结果数组
        res.push_back(make_pair(job.rbegin()->first, finish));
        //更新结束时间
        finish += job.rbegin()->second;
        job.pop_back();
    }
    //如果后面几个进入的作业都在上一个执行的作业结束之前进入
        while(!job.empty())
        {
            res.push_back(make_pair(job.rbegin()->first, finish));
            finish += job.rbegin()->second;
            job.pop_back();
        }
        sort(res.begin(), res.end(),cmp2);
        return res;
}

/*添加作业                                        */
/*输入:待添加的作业job,以及调度好的作业数组res*/
/*输出:添加作业之后的作业数组res               */
vector<pair<JCB, double>> Addjob(JCB job,vector<pair<JCB, double>>res)
{
    double tmp=job.in_time;
    vector<pair<JCB, double>>t_job;
    vector<pair<JCB, double>>res2;
    sort(res.begin(), res.end(), cmp3);
    if (job.in_time > res.rbegin()->second)//如果作业的进入时间比最后执行作业的执行时间还晚
    {
        res.push_back(make_pair(job, job.in_time));
        return res;
    }
    //将作业的执行时间从早到晚排序,将执行时间晚于作业进入时间的作业加入数组并
    //确定第一个执行的作业之后,重新调用作业调度函数
    queue<JCB>jobs;
    for (auto it = res.begin();it != res.end();it++)
    {
        //比较待添加的作业的进入时间和已经调度好的作业的开始执行时间
        //和待添加的作业的执行时间和已经调度好的作业的执行时间
        if (job.in_time > it->second||job.ex_time>=it->first.ex_time)continue;
        else
        {
            job.in_time = it->second;
            jobs.push(job);
            sort(it, res.end(), cmp4);
            for (auto it2 = res.end() - 1;it2 > it;)
            {
                jobs.push(it2->first);
                it2--;
                res.pop_back();
            }
            jobs.push(it->first);
            it--;
            res.pop_back();
            break;
        }
    }
    //重新调用作业调度函数
    res2=JobScheduling(jobs);
    res2.begin()->first.in_time = tmp;
    //将重新调度好的作业与不参与调度的作业连接
    res.insert(res.end(), res2.begin(), res2.end());
    sort(res.begin(), res.end(), cmp2);
    return res;
}
int main()
{
    queue<JCB>jobs;
    JCB job1, job2, job3, job4,job5;
    //初始作业队列
    job1 = { 1,8.00,2 };
    jobs.push(job1);
    job2 = { 2,8.50,0.50 };
    jobs.push(job2);
    job3 = { 3,9.00,0.10 };
    jobs.push(job3);
    job4 = { 4,11.60,0.20 };
    jobs.push(job4);

    //调用作业调度函数
    vector<pair<JCB, double>> res=JobScheduling(jobs);
    //输出作业状态表
    ShowJobChart(res);
    char i ;
    cout << "添加作业?(y/n):";
    cin >> i;
    while (i-‘y‘==0)
    {
        JCB job;
        cout << "请输入作业ID:";
        cin >> job.ID;
        cout << "请输入作业进入时间:";
        cin >> job.in_time;
        cout << "请输入作业执行时间:";
        cin >> job.ex_time;
        //添加作业
        vector<pair<JCB, double>> res = Addjob(job, JobScheduling(jobs));
        ShowJobChart(res);
        cout << "继续添加作业?(y/n):";
        cin >> i;
    }
}

运行结果截图

编译程序

运行程序

添加一个作业

继续添加一个作业

编译环境:Ubuntu

原文地址:https://www.cnblogs.com/bigyang/p/9017206.html

时间: 2024-10-11 10:28:27

模拟处理机作业调度---短作业优先调度算法的相关文章

短作业优先调度算法(SJF)

假设有n项作业位于就绪队列中,这些作业的提交时间用数组requestTimes按照提交时间的先后顺序存储,对应的作业服务时间(持续时间)用数组durations存储.采用SJF算法,计算n项作业的平均等待时间.当存在多个相同长度的短作业时,按照提交时间的先后顺序进行调度.假设0<= n <= 100.求出所有作业的平均等待时间. 函数原型:void minWaitingTime(int requestTimes[],int durations[],int n) 测试用例: 输入 40 2 4

【ZX笔试】短作业优先算法

时间复杂度为O(n*n),空间复杂度为O(n)的解法 1 // ShortJobFirst.cpp : 定义控制台应用程序的入口点. 2 // 3 4 #include "stdafx.h" 5 #include <iostream> 6 #include <vector> 7 8 using namespace std; 9 10 /* 11 每一步都计算当前时间和总的等待时间,根据当前时间(cpu_time)找到已经就绪的作业下标, 12 保存到vec_re

短作业调度算法

#include <stdio.h> struct sjf //定义进程的结构体{  char name[10]; //进程名 float arrivetime; //到达时间 float servicetime; //服务时间 float starttime;  //开始时间 float finishtime; //完成时间 float zztime; //周转时间 float dqzztime; //带权周转时间 };  sjf b[100]; //定义短作业优先算法进程的最大数量 voi

最短作业优先(SJF)

1. 最短作业优先: 最短作业优先(SJF)是一种调度任务请求的调度策略.每个任务请求包含有请求时间(即向系统提交的请求的时间)和持续时间(即完成任务所需时间). 当前任务完成后,SJF策略会选择最短持续时间执行任务,若最短持续时间相同,则选择最早请求时间的任务.任务等待时间为请求时间和实际开始时间之差.    "短作业优先"="最短剩余时间优先" 2. 实例: 假设系统一直执行任务,从未空闲.设计程序,输入请求时间表和对应的持续时间表,以及任务数量,计算平均等待时

短进程优先的调度算法详解

一.SPF算法简介 SJF算法 SJF(shortest job first)是以进程的运行时间长度作为优先级,进程运行时间越短,优先级越高. SJF算法的缺点 必须预知进程的运行时间.即使是程序员也很难准确估计进程运行时间.如果估计过低,系统就可能按估计的时间终止进程的运行,但此时进程并未完成,故一般都会偏长估计 对长进程不利.长进程的周转时间会明显地增长.可怕的是,SJF算法完全忽视进程等待时间,可能使进程等待时间过长,出现饥饿现象. 人机无法实现交互. 完全未考虑进程的紧迫程度.不能保证紧

常见的进程优先调度算法

什么是进程调度以及为什么有进程调度算法 无论是在批处理系统还是分时系统中,用户进程数一般都多于处理机数.这将导致它们互相争夺处理机.另外,系统进程也同样需要使用处理机.这就要求进程调度程序按一定的策略,动态地把处理机分配给处于就绪队列中的某一个进程,以使之执行. 常见的进程调度算法   先进先出算法 算法总是把处理机分配给最先进入就绪队列的进程,一个进程一旦分得处理机,便一直执行下去,直到该进程完成或阻塞时,才释放处理机. 例如,有三个进程P1.P2和P3先后进入就绪队列,它们的执行期分别是21

操作系统——进程调度之短进程优先

 1.什么是进程调度 无论是在批处理系统还是分时系统中,用户进程数一般都多于处理机数.这将导致它们互相争夺处理机.另外,系统进程也同样需要使用处理机.这就要求进程调度程序按一定的策略,动态地把处理机分配给处于就绪队列中的某一个进程,以使之执行. 2.处理机调度分类 高级.中级和低级调度作业从提交开始直到完成,往往要经历下述三级调度: 高级调度:(High-Level Scheduling)又称为作业调度,它决定把后备进程调入内存运行: 低级调度:(Low-Level Scheduling)又称为

使用appium模拟用户发送短信

一段简单粗糙的代码.主要是实现的功能是模拟用户发送短信的功能. python版本3.5.2 appium版本1.4.16.1 from appium import webdriver desired_caps = { 'platformName':'Android', 'platformVersion':'4.4.2', 'deviceName':'test', 'appPackage':'com.android.mms', 'appActivity':'com.android.mms.ui.C

最短作业优先调度

#include<stdio.h>#define Time int#define M 100typedef struct process{    char name[M];//进程名    int priority;//优先数    int reachtime;//到达时间    int needtime;//需要时间    int usedtime;//已用时间    int completetime;//完成时间    int time1;//周转时间内    int time2;//带权