磁盘驱动调度算法的模拟

来源:互联网 发布:ap6210 linux 编辑:程序博客网 时间:2024/05/17 08:28

一.           实验内容:

熟悉磁盘的结构以及磁盘的驱动调度算法的模拟,编程实现简单常用的磁盘驱动调度算法先来先服务(FIFO)、电梯调度算法、最短寻找时间优先算法、扫描(双向扫描)算法、单向扫描(循环扫描)算法等。编程只需实现两个算法。

题目可以选取教材或习题中的相关编程实例。

编程语言建议采用c/c++Java。模拟程序鼓励采用随机数技术、动态空间分配技术,有条件的最好能用图形界面展现甚至用动画模拟。

实验性质:验证型。

二.           实验目的和要求

1)掌握使用一门语言进行磁盘驱动调度算法的模拟;

2)编写程序将磁盘驱动调度算法的过程和结果能以较简明直观的方式展现出来。

三.           实验原理、方法和步骤

1. 实验原理

磁盘驱动调度对磁盘的效率有重要影响。磁盘驱动调度算法的好坏直接影响辅助存储器的效率,从而影响计算机系统的整体效率。

常用的磁盘驱动调度算法有:最简单的磁盘驱动调度算法是先入先出(FIFO)法。这种算法的实质是,总是严格按时间顺序对磁盘请求予以处理。算法实现简单、易于理解并且相对公平,不会发生进程饿死现象。但该算法可能会移动的柱面数较多并且会经常更换移动方向,效率有待提高。

  最短寻找时间优先算法:总是优先处理最靠近的请求。该算法移动的柱面距离较小,但可能会经常改变移动方向,并且可能会发生进程饥饿现象。

  电梯调度:总是将一个方向上的请求全部处理完后,才改变方向继续处理其他请求。

扫描(双向扫描):总是从最外向最里进行扫描,然后在从最里向最外扫描。该算法与电梯调度算法的区别是电梯调度在没有最外或最里的请求时不会移动到最外或最里柱面,二扫描算法总是移到最外、最里柱面。两端的请求有优先服被务的迹象。

循环扫描(单向扫描):从最外向最里进行柱面请求处理,到最里柱面后,直接跳到最外柱面然后继续向里进行处理。该算法与扫描算法的区别是,回来过程不处理请求,基于这样的事实,因为里端刚被处理。

 

2. 实验方法

1)使用流程图描述演示程序的设计思想;

2)选取c/c++Java等计算机语言,编程调试,最终给出运行正确的程序。

3. 程序设计

参考程序:

1)      c/c++版的驱动调度算法-电梯调度模拟程序

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <conio.h>

typedef struct _proc

{char name[32];           /*定义进程名称*/

int team;                /*定义柱面号*/

int ci;                  /*定义磁道面号*/

int rec;                 /*定义记录号*/

struct _proc *prior;

struct _proc *next;

}PROC;

 

PROC *g_head=NULL,*g_curr=NULL,*local;

int record=0;

int yi=1;

void init()

{

PROC *p;                                               /*初始化链表(初始I/O表)*/

g_head = (PROC*)malloc(sizeof(PROC));

g_head->next = NULL;

g_head->prior = NULL;

p = (PROC*)malloc(sizeof(PROC));

strcpy(p->name, "P1");

p->team=100;

p->ci=10;

p->rec=1;

p->next = NULL;

p->prior = g_head;

g_head->next = p;

g_curr=g_head->next;

p = (PROC*)malloc(sizeof(PROC));

strcpy(p->name, "P2");

p->team=30;

p->ci=5;

p->rec=5;

p->next = NULL;

p->prior = g_curr;

g_curr->next = p;

g_curr=p;

p = (PROC*)malloc(sizeof(PROC));

strcpy(p->name, "P3");

p->team=40;

p->ci=2;

p->rec=4;

p->next = NULL;

p->prior = g_curr;

g_curr->next = p;

g_curr=p;

p = (PROC*)malloc(sizeof(PROC));

strcpy(p->name, "P4");

p->team=85;

p->ci=7;

p->rec=3;

p->next = NULL;

p->prior = g_curr;

g_curr->next = p;

g_curr=p;

p = (PROC*)malloc(sizeof(PROC));

strcpy(p->name, "P5");

p->team=60;

p->ci=8;

p->rec=4;

p->next = NULL;

p->prior = g_curr;

g_curr->next = p;

g_curr=g_head->next;

local = (PROC*)malloc(sizeof(PROC));             /*选中进程*/

strcpy(local->name, "P0");

local->team=0;

local->ci=0;

local->rec=0;

local->next=NULL;

local->prior=NULL;

}

void PrintInit()                                 /*打印I/O*/

{

    PROC *t = g_head->next;

printf("-------------------------------------/n");

printf("   ---------I/O LIST---------/n");

printf(" process    team     ci    rec   /n");

while(t!=NULL)

{

printf("%4s %8d %8d %5d/n", t->name, t->team, t->ci, t->rec );

   t = t->next;

}

printf("/n/nCurrent process is :/n");

printf("------------------------------/n/n");

printf(" process    team     ci    rec   /n");

printf("%4s %8d %8d %5d/n", local->name, local->team, local->ci, local->rec );

switch(yi)

{

case 1:{printf("current direction is UP/n");break;}

case 0:{printf("current direction is down/n");break;}

}

}

void acceptreq()                        /*接受请求函数*/

{

PROC *p;

p = (PROC*)malloc(sizeof(PROC));

printf("please input the information of the new process/nprocess-name:/nprocess-team/nprocess-ci/nprocess-rec/n");

printf("1.name/n");

scanf("%s",p->name);

printf("2.team 0-199/n");

scanf("%d",&p->team);                    /*输入请求进程信息*/

printf("3.ci 0-19/n");

scanf("%d",&p->ci);

printf("4.rec 0-7/n");

scanf("%d",&p->rec);

getchar();

g_curr=g_head;                       /*将此节点链入I/O请求表*/

while(g_curr->next!=NULL)

g_curr=g_curr->next;

p->next=NULL;

p->prior=g_curr;

g_curr->next=p;

g_curr=g_head->next;

printf("NEW I/O LIST/n/n");

PrintInit();                      /*将新的I/O请求表输出*/

}

void qddd()                         /*驱动调度函数*/

{PROC *out;

int min;

int max=g_head->next->team;

if (g_head->next==NULL);            /*若已全部调度,则空操作*/

else{ switch (yi)

{case 1:  

{

min=g_head->next->team;out=g_head->next;          /*选出最小的team进程,模拟启动此进程*/

strcpy(local->name,out->name);

local->team=out->team;

local->ci=out->ci;

local->rec=out->rec;

for (g_curr=g_head->next;g_curr!=NULL;g_curr=g_curr->next)

{

if (g_curr->team > record)

{ min = g_curr->team;break;}

}

for (g_curr=g_head->next;g_curr!=NULL;g_curr=g_curr->next)

{

if (min>=g_curr->team&&g_curr->team>record)

{

min=g_curr->team;

out=g_curr;

strcpy(local->name,out->name);

local->team=out->team;

local->ci=out->ci;

local->rec=out->rec;

}

}

printf("/n-----------------------/n");

printf("the process choosed :/n");

 

printf(" process    team     ci    rec   /n");

printf("%4s %8d %8d %5d/n", out->name, out->team, out->ci,out->rec );

 

record = local->team;

printf("%d",record);

for (g_curr=g_head->next;g_curr!=NULL;g_curr=g_curr->next)

{

if (max<g_curr->team)

max=g_curr->team;

}

if(max==record)

{

yi=0;

record=1000;

break;

}

 

break;

}/*case 1*/

case 0:                                    /*case 1 的对称过程*/

{

max=g_head->next->team;out=g_head->next;     

strcpy(local->name,out->name);

local->team=out->team;

local->ci=out->ci;

local->rec=out->rec;

for (g_curr=g_head->next;g_curr!=NULL;g_curr=g_curr->next)

{

if (g_curr->team < record)

{ max = g_curr->team;break;}

}

for (g_curr=g_head->next;g_curr!=NULL;g_curr=g_curr->next)

{

if (max<=g_curr->team&&g_curr->team<record)

{

max=g_curr->team;

out=g_curr;

strcpy(local->name,out->name);

local->team=out->team;

local->ci=out->ci;

local->rec=out->rec;

}

}

printf("/n-----------------------/n");

printf("the process choosed :/n");

 

printf(" process    team     ci    rec   /n");

printf("%4s %8d %8d %5d/n", out->name, out->team, out->ci,out->rec );

min=g_head->next->team;

for (g_curr=g_head->next;g_curr!=NULL;g_curr=g_curr->next)

{

if (min>g_curr->team)

min=g_curr->team;

}

record = local->team;

if(min==record)

{

yi=1;

record=0;

break;

}

 

break;

}

default : return -1;

}/*switch*/

 

if (out->next==NULL)                      /*将选中的进程从I/O请求表中删除*/

{

out->prior->next=NULL;

free(out);

}

else

{

out->prior->next=out->next;

out->next->prior=out->prior;

free(out);

}

}/*else*/

 

}

void acceptnum()                             /*通过输入0~1选择‘驱动调度’或是‘接受请求’*/

{

float num;

char c;

while(1)

{

printf("----------------------------------------------/n");

printf("please input a number between 0 and 1/nnum<=0.5:accept request/nnum>0.5:qudong diaodu/n/nnum==2:I/O LIST/n/nnum=?/n");

scanf("%f",&num);

getchar();

while((num<0||num>1)&&num!=2)                /*过滤不合法数据 注意:本程序其他输入数据可能未过滤*/

{

printf("number ERROR!Input again please!/nnum=?/n ");

scanf("%f",&num);

getchar();

}

if(num>0.5&&num!=2)                         /*驱动调度*/

{

if (g_head->next==NULL)

{

printf("/n/n");

printf("---------------------/n");

printf("I/O list is empty!!!/n");           /*请求表为空 无需调度*/

}

else

{

printf("qudong diaodu/n");

qddd();

                                 /*调用函数进行调度*/

}

}

else if (num<=0.5)                          /*接受请求*/

{

printf("accept request/n/n");

acceptreq();

}

else if (num==2)                           /*通过输入2显示当前请求I/O*/

{

printf("I/O LIST;");

printf("-------------------/n");

PrintInit();

printf("/n");

}

 

printf("-----------------------/n");

printf("choose 'n' to quit else to continue/n");                  /*输入n离开本程序*/

if(strcmp(c=getchar(),'n')==0||strcmp(c=getchar(),'N')==0)

{

clrscr();

printf("/n/n/n/n/n/n");

printf("thank you for testing my program!/n");

printf("     ---by   01/n");

sleep(2);

printf("/n/nBYEbye!!");

sleep(2);

return -1;

}

else

{

clrscr();

}

}

}

main ()                           /*主程序*/

{

init();

PrintInit();

acceptnum();

}

四.           实验结果分析

能够将磁盘驱动调度算法在各种情况下都能得出正确的结论。对FIFO、最短寻找时间优先或电梯调度算法能够在多次模拟数据下得出平均移动柱面数,并进行效率比较分析。