西北农林科技大学操作系统实验二(2)——作业调度一设计测试实验_模拟单道批处理系统中作业调度实验-程序员宅基地

技术标签: 实验  操作系统  

编写并调试一个单道系统的作业调度模拟程序。

调度模型:描述调度模型.。(可以采用模块化方法并用框图说明)
作业调度算法:分别采用先来先服务(FCFS),最短作业优先(SJF)、响应比高者优先(HRN)的调度算法。
要求:
1) 定义JCB,并操作之。
2) 描述作业队列。
3) 对每种调度算法都要求打印每个作业开始运行时刻、完成时刻、周转时间、带权周转时间,以及这组作业的平均周转时间及带权平均 周转时间,以比较各种算法的优缺点。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<conio.h>
#define getpch(type) (type*)malloc(sizeof(type))
int n;//作业数//the num of jobs
float T1 = 0, T2 = 0;
int times = 0; //记录时间
void swap ( int *a, int *b );
//作业控制块
struct jcb
{
    
    char name[10];//?添加注释 //用户名称
    int reachtime;//?添加注释//作业抵达时间
    int starttime;//?添加注释//作业开始时间
    int needtime;//?添加注释//作业运行所需时间
    int finishtime;//作业完成时间
    float cycletime;//作业周转时间
    float cltime;//?添加注释//带权周转时间
    char state;//作业状态
    struct jcb *next;//结构体指针
    int Rp;//响应比——响应时间/要求服务时间
    int waittime;//等待时间
}*ready = NULL, *p, *q;

typedef struct jcb JCB;

void inital() //建立作业控制块队列,先将其排成先来先服务(FCFS)的模式队列
{
    
    int i;
    printf ( "\n输入作业数:" );
    scanf ( "%d", &n );
    for ( i = 0; i < n; i++ )
    {
    
        p = getpch ( JCB );
        printf ( "\n输入作业名:" );
        scanf ( "%s", p->name );
        getchar();
        p->reachtime = i;
        printf ( "作业默认到达时间:%d", i );
        printf ( "\n输入作业要运行的时间:" );
        scanf ( "%d", &p->needtime );
        p->state = 'W';
        p->next = NULL;
        if ( ready == NULL )
            ready = q = p;
        else
        {
    
            q->next = p;
            q = p;
        }
    }
}

void disp ( JCB*q, int m ) //显示作业运行后的周转时间及带权周转时间等
{
    
    printf ( "\n作业%s正在运行,估计其运行情况:\n", q->name );
    printf ( "开始运行时刻:%d\n", q->starttime );
    printf ( "完成时刻:%d\n", q->finishtime );
    printf ( "周转时间:%f\n", q->cycletime );
    printf ( "带权周转时间:%f\n", q->cltime );
    getchar();
}

void running ( JCB *p, int m ) //运行作业
{
    
    if ( p == ready )   //先将要运行的作业从队列中分离出来
    {
    
        ready = p->next;
        p->next = NULL;
    }
    else
    {
    
        q = ready;
        while ( q->next != p )  q = q->next;
        q->next = p->next;
    }
    p->starttime = times;//计算作业运行后的完成时间,周转时间等等
    p->state = 'R';
    p->finishtime = p->starttime + p->needtime;
    p->cycletime = ( float ) ( p->finishtime - p->reachtime );
    p->cltime = ( float ) ( p->cycletime / p->needtime );
    T1 += p->cycletime;
    T2 += p->cltime;
    disp ( p, m ); //调用disp()函数,显示作业运行情况
    times += p->needtime;
    p->state = 'F';
    printf ( "\n%s has been finished!\n", p->name );
    free ( p ); //释放运行后的作业
    getchar();
}

void final() //最后打印作业的平均周转时间,平均带权周转时间
{
    
    float s, t;
    t = T1 / n;
    s = T2 / n;
    getchar();
    printf ( "\n\n作业已经全部完成!\n" );
    printf ( "\n%d个作业的平均周转时间是:%f", n, t );
    printf ( "\n%d个作业的平均带权周转时间是%f:\n\n\n", n, s );
}

void sjf ( int m ) //最短作业优先算法(Short Job First,SJF)
{
    
    JCB *min;//定义作业控制块
    int i, iden;
    system ( "cls" );
    inital();// 将作业按照FCFS加入队列
    for ( i = 0; i < n; i++ )
    {
    
        p = min = ready;//分别初始化p、min、ready
        iden = 1;
        do
        {
    
            if ( p->state == 'W' && p->reachtime <= times ) //判断是否满足到达时间等于总时间和作业状态为‘w’
                if ( iden )
                {
    
                    min = p;
                    iden = 0;
                }
                else if ( p->needtime < min->needtime )
                    min = p;
            p = p->next;
            // 1 根据上下文,空格处填写一条指令
        }
        while ( p != NULL );
        if ( iden ) //如果没有满足条件的作业则总时间增加
        {
    
            i--;
            times++;
            if ( times > 100 )
            {
    
                printf ( "\nruntime is too long … error" );
                getchar();
            }
        }
        else
        {
    
            running ( min, m );//如果有则运行队列中的作业
        }
    }
    final();//更新系统时间
}

void fcfs ( int m )  //先来先服务算法
{
    

    int i, iden;
    system ( "cls" );
    inital();
    for ( i = 0; i < n; i++ )
    {
    

        p = ready;
        iden = 1;
        do
        {
    
            if ( p->state == 'W' && p->reachtime <= times )  iden = 0;
            if ( iden ) p = p->next;
        }
        while ( p != NULL && iden );//利用链表遍历找到队列中非空队首

        if ( iden ) //如果没有满足条件的作业则等待
        {
    
            i--;
            printf ( "\n没有满足要求的进程,需等待" );
            times++;
            // 2根据上下文,填入一条语句
            if ( times > 100 )
            {
    
                printf ( "\n时间过长" );
                getchar();
            }
        }
        else//如果有则运行作业
        {
    
            running ( p, m );
        }
    }
    final();//更新系统时间
}
void getPriority()
{
    
     p = ready;
    while ( p != NULL )
    {
    
        //如果到达时间比当前时间晚,则响应比为Ⅰ
        if ( times <= p->reachtime )
            p->Rp = 1;
        //如果到达时间比当前时间早,则响应比为(等待时间+要求服务时间)/要求服务时间
        else
            p->Rp=(double)(p->waittime+p->needtime)/(p->needtime);
    }
}
void HRN ( int m )
{
    
    int i,iden;
        JCB *max;
    system ( "cls" );
    inital();

      for(i=0; i<n; i++)
    {
    
        p=max=ready;
        iden=1;
        //找到响应比最大的可运行的作业
        do
        {
    
            if(p->state=='W'&&p->reachtime<=times)
            {
    
                if(iden)
                {
    
                    max=p;
                    iden=0;
                }
                else if(p->Rp > max->Rp)
                  max=p;
            }
            p=p -> next;
        }
        while (p != NULL);

        if(iden)
        {
    
            i--;
            times++;
            if (times>100)
            {
    
                printf("\nruntime is too long … error");
                getchar();
            }
        }
        else
        {
    
            running(max, m);
            getPriority();//运行完当前后对响应比重新定义
        }
    }
}
void menu()
{
    
    int m;
    system ( "cls" );
    printf ( "\n\n\t\t*********************************************\t\t\n" );
    printf ( "\t\t\t\t作业调度演示\n" );
    printf ( "\t\t*********************************************\t\t\n" );
    printf ( "\n\n\n\t\t\t1.先来先服务算法." );
    printf ( "\n\t\t\t2.最短作业优先算法." );
    printf ( "\n\t\t\t3.高响应比优先调度算法." );
    printf ( "\n\t\t\t0.退出程序." );
    printf ( "\n\n\t\t\t\t选择所要操作:" );
    scanf ( "%d", &m );//菜单
    switch ( m )
    {
    
    case 1:
        fcfs ( m );//利用FCFS算法运行作业
        getchar();
        system ( "cls" );
        break;
    case 2:
        sjf ( m );//利用SJF算法运行作业
        getchar();
        system ( "cls" );
        break;
    case 3:
        HRN(m);
        getchar();
        system("cls");
        break;
    case 0:
        system ( "cls" );
        break;
    default:
        printf ( "选择错误,重新选择." );
        getchar();
        system ( "cls" );
        menu();
    }
}
int main()
{
    
    menu();
    system ( "pause" );
    return 0;
}

hrn运行结果

在这里插入图片描述

多道批处理系统的程序设计

编写并调试一个多道系统的作业调度模拟程序。
调度模型:描述多道调度
模型。(可以采用模块化方法并用框图说明)
作业调度算法:先来先服务(FCFS)
要求:
1) 定义JCB,并操作之。
2) 描述作业队列。
3) 定义多道系统中的各种资源种类及数量、调度作业时必须考虑到每 个作业的资源要求。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define getpch(type) (type*)malloc(sizeof(type))
#define NUM_OF_RESOURCE 3
struct Resource
{
    
    char name[10];//资c源名
    int num;      //资源的数量
    int usedTime; //作业该资源耗时
    struct Resource *link;
};
typedef struct Resource resource;
struct jcb      //作业控制块
{
    
    char name[10];  // 作业名
    int reachtime;  //作业到达时间
    int rnum;       //作业所需资源的种类数
    int starttime;  //作业开始时间
    int needtime;
    int finishtime; //作业完成时间
    float cycletime;//作业周转时间
    float cltime;   //带权周转时间
    char state;     //作业状态
    int IsUsed;    //标志是否使用该资源
    resource *res;  //所需资源指针
    struct jcb *next;      //结构体指针
}*ready[4], *p, *q; //q用来指向当前节点
//创建四个队列,依次对应三种资源的就绪队列

int times  = 0;
typedef struct jcb JCB;

//资源插入作业
void InsertR ( JCB *p, resource *ptr )
{
    
    if ( p -> res == NULL )
    {
    
        p->res = ptr;
    }
    else
    {
    
        resource* pt = p -> res;
        while ( pt->link != NULL )
            pt = pt->link;
        pt -> link = ptr;
    }
}

//作业进入就绪队列,并根据到达时间进行排序
void InsertJobs ( JCB* p, int t )
{
    
    if ( ready[t] == NULL )
        ready[t] = p;
    else
    {
    
        JCB *pt = ready[t];
        q = pt->next;
        //比队首元素来得早,就待在队首
        if ( pt->reachtime > p->reachtime )
        {
    
            ready[t] = p;
            p->next = pt;
        }
        else
        {
    
            while ( q != NULL && q->reachtime <= p->reachtime )
            {
    
                pt = pt->next;
                q = pt->next;
            }
            if ( q == NULL )
            {
    
                pt->next = p;
            }
            else
            {
    
                pt->next = p;
                p->next = q;
            }
        }

    }
}
//输入m个作业
void init ( int m )
{
    
    resource *ptr;
    int i, j;
    printf ( "请输入作业数" );
    printf ( "%d \n", m );
    for ( i = 0; i < m; i++ )
    {
    
        p = getpch ( JCB );
        //
        printf ( "输入作业名: " );
        scanf ( "%s", p->name );
        printf ( "\n输入作业到达时间" );
        scanf ( "%d", &p->reachtime );
        printf ( "\n输入作业所需资源的种类数:" );
        scanf ( "%d", &p->rnum );
        p->res = NULL;
        for ( j = 0; j < p->rnum; j++ )
        {
    
            ptr = ( resource* ) malloc ( sizeof ( resource ) );
            printf ( "\n\t输入资源名: " );
            scanf ( "%s", ptr->name );
            printf ( "\n\t输入所需资源的数量: " );
            scanf ( "%d", &ptr->num );
            printf ( "\n\t输入该作业消耗该资源的时间: " );
            scanf ( "%d", &ptr->usedTime );
            p->IsUsed = 1; //默认都使用
            ptr->link = NULL;
            InsertR ( p, ptr );
        }
        p->state = 'W';//W表示就绪状态
        p->next = NULL;
        InsertJobs   ( p, 0 ); //把p插入后备队列
    }
}
void Running(JCB *p, int j, resource *cre)
{
    
    printf("%s的调度结果:\n", cre[j].name);
    printf("作业名为:%s\n", p->name);
    printf("到达该资源的时间:%d\n", p->reachtime);
    p->reachtime = p->starttime+p->needtime;
    printf("释放该资源的时间%d\n",p->reachtime);
    InsertJobs(p, j+1);
}
//调度算法
void FCFS ( resource *cre )
{
    
    int j = 0;
    for ( j = 0; j < 3; j++ )
    {
    
        printf ( "\n" );
        p = ready[j];
        if ( p != NULL )
        {
    
            ready[j] = p->next;
            p->next = NULL;//脱离原队列
        }
        while ( p != NULL )
        {
    
            //寻找p中所含的资源数
            resource * ptr = p->res;
            while ( ptr != NULL && strcmp ( ptr->name, cre[j].name ) )
            {
    
                ptr = ptr->link;
            }
            //作业需要该资源数量目小于等于现存资源数或不需要该资源,则执行p
            if ( ptr != NULL && ptr->num <= cre[j].num )
            {
    
                //如果当前时刻小于到达时刻,则当前时刻应当到到达时刻才能运行
                if ( times <= p->reachtime )
                {
    
                    times = p->reachtime;
                }
                if ( ptr == NULL )
                {
    
                    p->starttime = times;
                    p->needtime = 0;
                    p->IsUsed = 0; //标志为不需要该资源
                    Running ( p, j, cre );
                }
                //需要该资源则应从系统资源中减去所需的数目
                else
                {
    
                    p->starttime = times;
                    p->needtime = ptr->usedTime;
                    cre[j].num -= ptr->num;
                    Running ( p, j, cre );
                }
                //执行下一个作业
                p = ready[j];
                if ( p != NULL )
                {
    
                    ready[j] = p->next;
                    p->next = NULL;
                }

            }
            else
            {
    
                JCB*q1;
                q1 = ready[j + 1];
                //找到第一个使用该资源的且未释放的进程q1
                while ( q1 != NULL && q1->IsUsed == 0 )
                    q1 = q1->next;
                if ( q1 == NULL )
                    return;
                times = q1->reachtime;
                resource* ptr1 = q1->res;
                while ( ptr1 != NULL && strcmp ( ptr1->name, cre[j].name ) )
                    ptr1 = ptr1->link;
                if ( ptr1 == NULL )
                    return;
                cre[j].num += ptr1->num;
                q1->IsUsed = 0;
            }

        }
        times=0;//重设时间
        JCB* pt = ready[j+1];
        while (pt != NULL)
        {
    
            pt ->IsUsed = 1;
            pt = pt ->next;
        }

    }
}
int main()
{
    
    int m;
    resource cre[3];//计算机资源
    //初始化计算机资源0为输入设备,1为cpu,2为输出设备
    //输入设备
    strcpy(cre[0].name, "INS");
    cre[0].num = 2;
    //CPU
    strcpy(cre[1].name, "CPU");
    cre[1].num = 4;
    //输出设备
    strcpy(cre[2].name, "OUTS");
    cre[2].num = 2;
    //初始化三个队列
    int id=0;
    for(id=0; id<4; id++)
        ready[id]=NULL;
    //输入m个作业
    printf("输入要输入的作业总数: ");
    scanf("%d", &m);
    getchar();
    init(m);
    FCFS(cre);
    q = ready[3];
    while(q != NULL)
    {
    
        ready[3] = q -> next;
        free(q);
        q=q->next;
    }
    return 0;
}

运行结果
在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_44029810/article/details/107464642

智能推荐

攻防世界_难度8_happy_puzzle_攻防世界困难模式攻略图文-程序员宅基地

文章浏览阅读645次。这个肯定是末尾的IDAT了,因为IDAT必须要满了才会开始一下个IDAT,这个明显就是末尾的IDAT了。,对应下面的create_head()代码。,对应下面的create_tail()代码。不要考虑爆破,我已经试了一下,太多情况了。题目来源:UNCTF。_攻防世界困难模式攻略图文

达梦数据库的导出(备份)、导入_达梦数据库导入导出-程序员宅基地

文章浏览阅读2.9k次,点赞3次,收藏10次。偶尔会用到,记录、分享。1. 数据库导出1.1 切换到dmdba用户su - dmdba1.2 进入达梦数据库安装路径的bin目录,执行导库操作  导出语句:./dexp cwy_init/[email protected]:5236 file=cwy_init.dmp log=cwy_init_exp.log 注释:   cwy_init/init_123..._达梦数据库导入导出

js引入kindeditor富文本编辑器的使用_kindeditor.js-程序员宅基地

文章浏览阅读1.9k次。1. 在官网上下载KindEditor文件,可以删掉不需要要到的jsp,asp,asp.net和php文件夹。接着把文件夹放到项目文件目录下。2. 修改html文件,在页面引入js文件:<script type="text/javascript" src="./kindeditor/kindeditor-all.js"></script><script type="text/javascript" src="./kindeditor/lang/zh-CN.js"_kindeditor.js

STM32学习过程记录11——基于STM32G431CBU6硬件SPI+DMA的高效WS2812B控制方法-程序员宅基地

文章浏览阅读2.3k次,点赞6次,收藏14次。SPI的详情简介不必赘述。假设我们通过SPI发送0xAA,我们的数据线就会变为10101010,通过修改不同的内容,即可修改SPI中0和1的持续时间。比如0xF0即为前半周期为高电平,后半周期为低电平的状态。在SPI的通信模式中,CPHA配置会影响该实验,下图展示了不同采样位置的SPI时序图[1]。CPOL = 0,CPHA = 1:CLK空闲状态 = 低电平,数据在下降沿采样,并在上升沿移出CPOL = 0,CPHA = 0:CLK空闲状态 = 低电平,数据在上升沿采样,并在下降沿移出。_stm32g431cbu6

计算机网络-数据链路层_接收方收到链路层数据后,使用crc检验后,余数为0,说明链路层的传输时可靠传输-程序员宅基地

文章浏览阅读1.2k次,点赞2次,收藏8次。数据链路层习题自测问题1.数据链路(即逻辑链路)与链路(即物理链路)有何区别?“电路接通了”与”数据链路接通了”的区别何在?2.数据链路层中的链路控制包括哪些功能?试讨论数据链路层做成可靠的链路层有哪些优点和缺点。3.网络适配器的作用是什么?网络适配器工作在哪一层?4.数据链路层的三个基本问题(帧定界、透明传输和差错检测)为什么都必须加以解决?5.如果在数据链路层不进行帧定界,会发生什么问题?6.PPP协议的主要特点是什么?为什么PPP不使用帧的编号?PPP适用于什么情况?为什么PPP协议不_接收方收到链路层数据后,使用crc检验后,余数为0,说明链路层的传输时可靠传输

软件测试工程师移民加拿大_无证移民,未受过软件工程师的教育(第1部分)-程序员宅基地

文章浏览阅读587次。软件测试工程师移民加拿大 无证移民,未受过软件工程师的教育(第1部分) (Undocumented Immigrant With No Education to Software Engineer(Part 1))Before I start, I want you to please bear with me on the way I write, I have very little gen...

随便推点

Thinkpad X250 secure boot failed 启动失败问题解决_安装完系统提示secureboot failure-程序员宅基地

文章浏览阅读304次。Thinkpad X250笔记本电脑,装的是FreeBSD,进入BIOS修改虚拟化配置(其后可能是误设置了安全开机),保存退出后系统无法启动,显示:secure boot failed ,把自己惊出一身冷汗,因为这台笔记本刚好还没开始做备份.....根据错误提示,到bios里面去找相关配置,在Security里面找到了Secure Boot选项,发现果然被设置为Enabled,将其修改为Disabled ,再开机,终于正常启动了。_安装完系统提示secureboot failure

C++如何做字符串分割(5种方法)_c++ 字符串分割-程序员宅基地

文章浏览阅读10w+次,点赞93次,收藏352次。1、用strtok函数进行字符串分割原型: char *strtok(char *str, const char *delim);功能:分解字符串为一组字符串。参数说明:str为要分解的字符串,delim为分隔符字符串。返回值:从str开头开始的一个个被分割的串。当没有被分割的串时则返回NULL。其它:strtok函数线程不安全,可以使用strtok_r替代。示例://借助strtok实现split#include <string.h>#include <stdio.h&_c++ 字符串分割

2013第四届蓝桥杯 C/C++本科A组 真题答案解析_2013年第四届c a组蓝桥杯省赛真题解答-程序员宅基地

文章浏览阅读2.3k次。1 .高斯日记 大数学家高斯有个好习惯:无论如何都要记日记。他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210后来人们知道,那个整数就是日期,它表示那一天是高斯出生后的第几天。这或许也是个好习惯,它时时刻刻提醒着主人:日子又过去一天,还有多少时光可以用于浪费呢?高斯出生于:1777年4月30日。在高斯发现的一个重要定理的日记_2013年第四届c a组蓝桥杯省赛真题解答

基于供需算法优化的核极限学习机(KELM)分类算法-程序员宅基地

文章浏览阅读851次,点赞17次,收藏22次。摘要:本文利用供需算法对核极限学习机(KELM)进行优化,并用于分类。

metasploitable2渗透测试_metasploitable2怎么进入-程序员宅基地

文章浏览阅读1.1k次。一、系统弱密码登录1、在kali上执行命令行telnet 192.168.26.1292、Login和password都输入msfadmin3、登录成功,进入系统4、测试如下:二、MySQL弱密码登录:1、在kali上执行mysql –h 192.168.26.129 –u root2、登录成功,进入MySQL系统3、测试效果:三、PostgreSQL弱密码登录1、在Kali上执行psql -h 192.168.26.129 –U post..._metasploitable2怎么进入

Python学习之路:从入门到精通的指南_python人工智能开发从入门到精通pdf-程序员宅基地

文章浏览阅读257次。本文将为初学者提供Python学习的详细指南,从Python的历史、基础语法和数据类型到面向对象编程、模块和库的使用。通过本文,您将能够掌握Python编程的核心概念,为今后的编程学习和实践打下坚实基础。_python人工智能开发从入门到精通pdf

推荐文章

热门文章

相关标签