二级任务调度C++模拟 操作系统

目的 

通过模拟操作系统任务调度原理的实现,加深对操作系统工作原理和操作系统实现方法的理解。

具体要求如下:

  1. 采取模块化方式进行程序设计,要求程序的功能设计、数据结构设计及整体结构设计合理。也可根据自己对题目的理解增加新的功能模块。
  2. 系统以菜单界面方式(至少采用文本菜单界面,如能采用图形菜单界面更好)工作,运行界面友好,演示程序以用户和计算机的对话方式进行。
  3. 程序算法说明清晰,理论分析与计算正确,运行情况良好,实验测试数据无误,容错性强(能对错误输入进行判断控制)。
  4. 编程风格良好(包括缩进、空行、适当注释、变量名和函数名见名知意,程序容易阅读等);

主要内容

某系统采用二级任务调度,第一级作业调度采用高响应比优先策略,第二级进程调度采用时间片轮转策略。假设内存最多容纳M个进程,进程不会发生阻塞,也不会被挂起。

(1)输入各个进程的进入时间和运行时间。

(2)计算各个进程的开始时间、结束时间、周转时间、带权周转时间,并直观输出显示。

(3)使用一个日志文件记录具体的调度信息。

概要设计 

1.系统采用二级任务调度,第一级作业调度采用高响应比优先策略,第二级进程调度采用时间片轮转策略。

        建立作业结构体,统一作业属性,减少空间消耗,方便管理。用作业队列存储作业,利于进行调度与计算。同时也可以用于输出,提高代码空间复用性。

        一级作业调度使用队列存储JCB,队头位置进行CPU运行二级调度。只需要一个队列就能同时进行作业调度与进程调度,减少时间复杂度,同时设置相应属性与函数保证队列与容器内容相同,防止调度出错,增加容错性,两个循环互不影响,不用嵌套循环,时间复杂度为O(N)。时间按时间片运行或以程序结束为标志前进,时间上比按每一分钟运行判断更快,实际运行速度远快于线性的时间复杂度。

2.二级任务调度,模块化方式进行程序设计。

        创建JCB结构体,存储作业名,响应比,是否运行标志,开始时间、结束时间、周转时间、带权周转时间等,用于作业调度的计算。

        使用vector容器存储,并可以用于输出结果。

        响应比高者优先(HRRN)调度算法,为每个作业设置一个优先权(响应比),调度之前先计算各作业的优先权,优先数高者优先调度。

        RP (响应比)= 作业周转时间 / 作业运行时间=1+作业等待时间/作业运行时间

 

3.使用一个日志文件记录具体的调度信息。

        使用fstream头文件中相应函数与IO流控制输出与文件读写。使用ofstream读写文件,ios::out|ios::ate|ios::app控制文件读写与输出。

        以ios::app打开(或者“ios::app|ios::out”),如果没有文件,那么生成空文件,如果有文件,那么在文件尾追加。

4.计算各个进程的开始时间、结束时间、周转时间、带权周转时间,并直观输出显示。

        使用作业队列容器中相应的排序函数对作业进行排序。初始化数据后使用循环,计算响应比并排序。

        通过参数与循环,在条件语句中对时间前进和使用不同条件对相应数据进行计算,通过控制输出格式与相应方法设置输出。

详细代码

详细设计

1、作业调度

   设置作业块:

struct JCB{

    string  name;                   //作业名

    int comeTime;                   //进入时间

    int memTime;                    //进入内存时间

    int beginTime;                  //开始运行时间

    int serverTime;                 //需要运行的时间

    int runTime;                    //已经运行的时间

    int FinishTime;                 //完成时间

    int turnAroundTime;             //周转时间

    bool   flag;                    //判断是否运行过

    double ResRatio;                //响应比

    double WeightedTurnAroundTime;  //带权周转时间

};

队列作一级调度内存,初始化完成入队。

        jcb[i].beginTime = -1;//开始运行时间初始化

        jcb[i].ResRatio = -1;//响应比初始化

        jcb[i].memTime = -1;//进入内存时间初始化

        jcb[i].runTime = 0;//运行时间初始化

        jcb[i].flag = 0;//入队标志初始化为0

只有当时间大于到来时间才有响应比(能入队),同时响应比为-2的也不参与计算。根据进入时间排序, 初始化完成入队。响应比控制入队,时间随循环不断增加,控制好循环与时间的关系,防止出错。

2、进程调度

时间片大于等于需要运行的时间时:

            time += (q.front().serverTime-q.front().runTime);

            q.front().runTime = q.front().serverTime;

            q.front().FinishTime = time;

            q.front().ResRatio = -2;//作业完成后响应比置为-2

            upDate(jcb,q,n);//出队前赋值

            q.pop();

            if(q.front().beginTime == -1){

                q.front().beginTime = time;

            }

            calResRatio(jcb,n,time);//计算响应比并排序

            for(int i = 0; i < n;i++){

                if(jcb[i].comeTime <= time && jcb[i].flag == 0&&

                        (int)q.size()<m&&jcb[i].ResRatio >= 0){

                    jcb[i].memTime = time;//进入内存时间等于当前时间

                    jcb[i].flag = 1;

                    q.push(jcb[i]);

                }

            }

            finishCount++;

否则time += TimeSlice;时间按时间片正常运行,队头未运行完成JCB再进入队尾等待。

        for(int i = 0; i < n;i++){

                if(jcb[i].comeTime <= time && jcb[i].flag == 0&&

                        (int)q.size()<m&&jcb[i].ResRatio >= 0){

                    jcb[i].memTime = jcb[i].comeTime;//进入内存时间等于到来时间

                    jcb[i].flag = 1;

                    q.push(jcb[i]);

                }

            }

            upDate(jcb,q,n);//出队前赋值

            JCB temp = q.front();//临时保存

            q.pop();//出队

            if(q.front().beginTime == -1){

                q.front().beginTime = time;

            }

            q.push(temp);//再加入队尾
        }

3、结果输出

根据进入时间排序vector,将vector中数据通过#include <iomanip>控制输出与文件的输出。再把输出时间转换为24小时制。

void userGuide(){

    cout<<"此系统采用二级任务调度,第一级作业调度采用高响应比优先策略,第二级进程调度采用时间片轮转策略。"<<endl;

    cout<<"系统会计算各个进程的进入内存时间、开始时间、结束时间、周转时间、带权周转时间,并直观输出显示。"<<endl;

    cout<<"同时系统会输出日志文件至D:\\操作系统课设\\record.txt(若无文件则自动生成)"<<endl;

    cout<<"----------------------------------------------"<<endl;

}

结果打印函数:

void printResult(int hour,int min,ofstream &fileout){

    //结果打印

    cout<<setw(15)<<hour<<":";

    fileout<<setw(18)<<hour<<":";

    if(min == 0){

        cout<<"00";

        fileout<<"00";

    }else if (min < 10) {

        cout<<"0";

        fileout<<"0";

        cout<<min;

        fileout<<min;

    }else {

        cout<<min;

        fileout<<min;

    }

主函数输出控制:

for (int i = 0; i < n;i++) {

        jcb[i].turnAroundTime = jcb[i].FinishTime-jcb[i].comeTime;//周转时间

        jcb[i].WeightedTurnAroundTime = jcb[i].turnAroundTime*1.0/jcb[i].serverTime;

        int outTimeHour = 0,outTimeMin = 0;

        cout<<setiosflags(ios::right);

        fileout<<setiosflags(ios::right);

        cout<<jcb[i].name;

        fileout<<jcb[i].name;

        //输出时间转换为24小时制

        outTimeHour = jcb[i].comeTime/60;

        outTimeMin = jcb[i].comeTime%60;

        printResult(outTimeHour,outTimeMin,fileout);

        outTimeHour = jcb[i].memTime/60;

        outTimeMin = jcb[i].memTime%60;

        printResult(outTimeHour,outTimeMin,fileout);

        outTimeHour = jcb[i].beginTime/60;

        outTimeMin = jcb[i].beginTime%60;

        printResult(outTimeHour,outTimeMin,fileout);

        outTimeHour = jcb[i].FinishTime/60;

        outTimeMin = jcb[i].FinishTime%60;

        printResult(outTimeHour,outTimeMin,fileout);

        cout<<setw(15)<<jcb[i].turnAroundTime

        <<setw(17)<<fixed<<setprecision(1)<<jcb[i].WeightedTurnAroundTime<<endl;

        fileout<<setw(19)<<jcb[i].turnAroundTime

        <<setw(18)<<fixed<<setprecision(1)<<jcb[i].WeightedTurnAroundTime<<endl;

}

结果测试

基本功能及作业调度与进程调度测试

基本功能正确运行。菜单界面正常。

高响应比作业晚到测试

 内存空间设置为3测试

日志文件写入测试

用户指引

此系统采用二级任务调度,第一级作业调度采用高响应比优先策略,第二级进程调度采用时间片轮转策略。

系统会计算各个进程的进入内存时间、开始时间、结束时间、周转时间、带权周转时间,并直观输出显示。

同时系统会输出日志文件至D:\\操作系统课设\\record.txt(若无文件则自动生成)

请输入进程数:

请输入内存容量:

请输入时间片(min):

输入第1个作业名:x

输入作业x进入时间(HH:MM):

输入作业x运行时间:

附赠输入样例


//基本功能
5
2
20
A
10:00
50
B
10:20
40
C
10:30
20
D
10:40
30
E
11:00
40

//高响应比后到
5
2
20
A
10:00
50
B
10:20
40
C
10:30
200
D
10:40
10
E
11:00
40


//时间片短
5
2
5
A
8:00
40
B
8:30
30
C
8:35
30
D
8:40
20
E
9:00
40

//3个内存
5
3
20
A
10:00
50
B
10:20
40
C
10:30
20
D
10:40
30
E
11:00
40

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
一、实验目的 本实验要求学生模拟作业调度的实现,用高级语言编写和调试一个或多个作业调度的模拟程序,了解作业调度操作系统中的作用,以加深对作业调度算法的理解。 二、实验内容和要求 1、编写并调度一个多道程序系统的作业调度模拟程序。   作业调度算法:采用基于先来先服务的调度算法。可以参考课本中的方法进行设计。 对于多道程序系统,要假定系统中具有的各种资源及数量、调度作业时必须考虑到每个作业的资源要求。 三、实验主要仪器设备和材料 硬件环境:IBM-PC或兼容机 软件环境:C语言编程环境 四、实验原理及设计方案 采用多道程序设计方法的操作系统,在系统中要经常保留多个运行的作业,以提高系统效率。作业调度从系统已接纳的暂存在输入井中的一批作业中挑选出若干个可运行的作业,并为这些被选中的作业分配所需的系统资源。对被选中运行的作业必须按照它们各自的作业说明书规定的步骤进行控制。 采用先来先服务算法算法模拟设计作业调度程序。 (1)、作业调度程序负责从输入井选择若干个作业进入主存,为它们分配必要的资源,当它们能够被进程调度选中时,就可占用处理器运行。作业调度选择一个作业的必要条件是系统中现有的尚未分配的资源可满足该作业的资源要求。但有时系统中现有的尚未分配的资源既可满足某个作业的要求也可满足其它一些作业的要求,那么,作业调度必须按一定的算法在这些作业中作出选择。先来先服务算法是按照作业进入输入井的先后次序来挑选作业,先进入输入井的作业优先被挑选,当系统中现有的尚未分配的资源不能满足先进入输入井的作业时,那么顺序挑选后面的作业。 (2) 假定某系统可供用户使用的主存空间共100k,并有5台磁带机。 3)流程图:
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kun.A.A

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值