操作系统实验 作业调度算法 先来先服务FCFS调度算法

作业调度算法 先来先服务FCFS调度算法

  1. 作业调度的原理:
    非抢占调度 把作业从外存调入内存
  2. 作业调度算法:
    先来先服务FCFS 短作业优先SJF 静态优先级调度 高响应比优先调度
  3. 实验原理
    作业调度算法:采用先来先服务(FCFS)调度算法,即按作业提交的/到达的(到达后备队列的时间)先后次序进行调度。从外存后备队列中选择几个最先进入该队列的作业,总是首先调度最先到达(可以理解为在系统中等待时间越长,优先级越高)的作业进入内存,为他们分配资源、创建进程,然后再放入就绪队列。 每个作业由一个作业控制块JCB表示,JCB可以包含如下信息:作业名、提交时间、所需的运行时间、作业状态等等。

作业的状态可以是等待W(Wait)、运行R(Run)和完成F(Finish)三种状态之一。每个作业的最初状态总是等待W。 各个等待的作业按照提交时刻的先后次序排队,总是首先调度等待队列中队首的作业。

每个作业完成后要输出该作业的开始运行时刻、完成时刻、周转时间和带权周转时间,这一组作业完成后计算并输出这组作业的平均周转时间、平均带权周转时间。
2)SJF调度算法:在提交时间相同(已到达外存作业后备队列的)时,按作业估计运行时间的长短进行调度。

  1. 以下为实验:先来先服务(FCFS)调度算法
  2. 周转时间 = 完成时间 - 提交时间周转时间 = 运行时间 + 等待时间
  3. 带权周转时间 = 周转时间 / 运行时间
#include<stdio.h>
#include<stdlib.h>

//操作系统实验:(作业调度算法)先来先服务FCFS调度算法

typedef struct JCB {
	int id;//作业序号
	char state;//当前作业状态
	int at;//作业提交时间
	int rt;//作业运行时间
	int st;//作业开始时间
	int ft;//作业完成时间
	float zt;//周转时间
	float dt;//带权周转时间
	struct JCB* next;
}*work, jcb;
jcb* creatwork(int x, int y, int z) {
	work newwork = (work)malloc(sizeof(jcb));
	newwork->id = x;
	newwork->state = 'W';
	newwork->at = y;
	newwork->rt = z;
	newwork->st = 0;
	newwork->ft = 0;
	newwork->dt = 0.00f;
	newwork->zt = 0.00f;
	newwork->next = NULL;

	return newwork;
}
void delwork(jcb *n, int x) { //删除作业已经完成了的结点
	work d;
	if (n != NULL) {
		while (n->next->id != x) {
			n = n->next;
		}
		d = n->next;
		n->next = d->next;
		free(d);
	}
}

float zt = 0, dt = 0;  //zt用于记录总周转时间,dt记录总带权周转时间

void disp(jcb* q1) /*建立作业显示函数,用于显示当前作业*/
{
	printf("\n id \t state \t at \t rt \t st \t ft \t zt \t dt \n");
	printf("|%d\t", q1->id);  // 格式输出的问题,之前用(int数据)以%s输出,导致了程序中断
	printf("|%c\t", q1->state);
	printf("|%d\t", q1->at);
	printf("|%d\t", q1->rt);
	printf("|%d\t", q1->st);
	printf("|%d\t", q1->ft);
	printf("|%f\t", q1->zt);
	printf("|%f\t", q1->dt);
	printf("\n该作业周转时间为 %.0f \n", q1->zt);
	zt += q1->zt;
	printf("该作业带权周转时间为 %.2f \n", q1->dt);
	dt += q1->dt;
	printf("\n");
}


void count(jcb* point, int num) {
	jcb *q, *p;//q用于记录最先提交的作业位置及当前作业,p用于遍历链表
	float time = 0, _num = num; //time记录当前时间,建个作业数目的变量副本_num
	jcb* p1 = point;

	while (_num != 0) {
		p = point->next;
		q = p;
		//循环排序 按提交时间
		while (p != NULL) {
			if (p->at < q->at) {
				q = p;
			}
			p = p->next;

		}

		printf("当前执行的作业序号为 work%d", q->id);
		if (time <= q->at) {
			q->state = 'R';
			q->st = q->at;
			time = q->rt + q->at;

		}
		else {
			q->state = 'R';
			q->st = time;
			time = time + q->rt;
			q->ft = time;

		}

		//保存信息
		q->zt = time - q->at;
		q->dt = (time - q->at) / q->rt;

		//正在运行的作业显示输出
		disp(q);

	/*	//其他状态的作业显示输出 没成功 如你有好的思路可以留言探讨
		while(p1 != NULL)
		{
			if (p1 == q)
				break;
			else
				disp(p1);
			p1 = p1->next;
		}*/

		delwork(point, q->id);
		--_num;

	}

	printf("\n");
	printf("平均周转时间为 %.2f \n", zt / num);
	printf("平均带权周转时间为 %.2f \n", dt / num);
}
int main() {
	int n, i, y, z;
	work tail = NULL;
	work head = NULL;
	printf("请输入作业数量:");
	scanf_s("%d", &n);
	tail = (work)malloc(sizeof(jcb));
	head = tail;
	for (i = 1; i <= n; i++) {
		printf("请输入work%d号作业的提交时间、运行时间:", i);
		scanf_s("%d%d", &y, &z);
		tail->next = creatwork(i, y, z);
		tail = tail->next;
	}
	count(head, n);

	system("pause");
	return 0;
}

实验室代码:

#include "stdio.h"
#include <stdlib.h>
#include <conio.h>
#define getpch(type) (type*)malloc(sizeof(type))
#define NULL 0

//FCFS 先来先服务算法2

//定义作业jcb结构体
struct jcb
{
    char name[100];
    char state;
    int tr;//作业提交时间
    int tn;//作业运行时间
    int ts;//作业开始时间
    int tf;//作业完成时间
    float ti;//作业周转时间
    float wi;//作业带权周转时间
    struct jcb* link;
}*ready=NULL,*h,*p;
typedef struct jcb JCB;


int time= 0;
int num = 0; //作业数量
//JCB *channel[100];
//fcfs算法实现
void sort() /* 建立对作业进行提交时间排列函数*/
{
    JCB *first, *second;
    int insert=0;
    if((ready==NULL)||((p->tr)<(ready->tr))) /*提交时间最小者,插入队首*/
    {
        p->link=ready;
        ready=p;
    }
    else /* 进程比较提交时间,插入适当的位置中*/
    {
        first=ready;
        second=first->link;
        while(second!=NULL)
        {
            if((p->tr)<(second->tr)) /*若插入作业比当前作业提交时间小,*/
            {
                /*插入到当前进程前面*/
                p->link=second;
                first->link=p;
                second=NULL;
                insert=1;
            }
            else /* 插入进程提交时间最高,则插入到队尾*/
            {
                first=first->link;
                second=second->link;
            }
        }
        if(insert==0) first->link=p;
    }
}


void input() /* 建立作业控制块函数*/
{
    int i;
//clrscr(); /*清屏*/
    printf("\n 请输入作业数量?");
    scanf("%d",&num);
    for(i=0; i<num; i++)
    {
        printf("\n 作业号No.%d:\n",i);
        p=getpch(JCB);
        printf("\n 输入作业名:");
        scanf("%s",p->name);
        printf("\n 输入作业提交时间:");
        scanf("%d",&p->tr);
        printf("\n 输入作业运行时间:");
        scanf("%d",&p->tn);
        printf("\n");
        p->ts=0;
        p->tf=0;
        p->ti=0.0f;
        p->wi=0.0f;
        p->state='w';
        p->link=NULL;
        sort(); /* 调用sort函数*/
    }
}

int space()
{
    int l=0;
    JCB* pr=ready;
    while(pr!=NULL)
    {
        l++;
        pr=pr->link;
    }
    return(l);
}
void destroy() /*建立作业撤消函数(进程运行结束,卸载作业)*/
{
    printf("\n 作业[%s] 已完成.\n",p->name);
    free(p);
}
void running() /* 建立作业就绪函数(作业运行时间到,置就绪状态*/
{

    if(p->link==NULL)
        destroy(); /* 调用destroy函数*/
}
void disp(JCB * pr) /*建立作业显示函数,用于显示当前作业*/
{
    printf("\n jname \t state \t tr \t tn \t ts \t tf \t ei \t wi \n");
    printf("|%s\t",pr->name);
    printf("|%c\t",pr->state);
    printf("|%d\t",pr->tr);
    printf("|%d\t",pr->tn);
    printf("|%d\t",pr->ts);
    printf("|%d\t",pr->tf);
    printf("|%f\t",pr->ti);
    printf("|%f\t",pr->wi);
    printf("\n");
}
void check() /* 建立作业查看函数 */
{
    JCB* pr;
    printf("\n **** 当前正在运行的作业是:%s",p->name); /*显示当前运行作业*/


    //累加变量time 记录当前用时 !!!
    if(time >= p->tr)
    {
        p->ts=time;
        p->tf=p->ts+p->tn;
        time = p->tf;
    }
    else
    {
        p->ts=p->tr;
        p->tf=p->ts+p->tn;
        time= p->tf;
    }

    p->ti = p->tf - p->tr;
    p->wi = p->ti / p->tn;
	//!!!

    disp(p);
    pr=ready;
    printf("\n ****当前就绪队列状态为:\n"); /*显示就绪队列状态*/
    while(pr!=NULL)
    {
        disp(pr);
        pr=pr->link;
    }
}
int main() /*主函数*/
{
    int len,h=0;
    float eti=0.0;
    float ewi=0.0;
    char ch;
    input();
    len=space();
    while((len!=0)&&(ready!=NULL))
    {
        ch=getchar();
        h++;
        printf("\n The execute number:%d \n",h);
        p=ready;
        ready=p->link;
        p->link=NULL;
        p->state='R';
        check();

        //保存信息
        eti+=p->ti;
        ewi+=p->wi;

        running();
        printf("\n 按任一键继续......");
        ch=getchar();

    }
    printf("\n\n 作业已经完成.\n");
    ch=getchar();

    eti/= num;
    ewi/= num;

    printf("\n该组作业平均周转时间为:%0.2f",eti);
    printf("\n该组作业平均带权周转时间为:%0.2f",ewi);
    return 0;
}

实验运行截图:
fcfs1

fcfs2
fcfs3

  • 27
    点赞
  • 231
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值