IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C语言模拟实现硬盘柱面访问调度算法 -> 正文阅读

[C++知识库]C语言模拟实现硬盘柱面访问调度算法

1 内容:硬盘调度。

编写 C 程序模拟实现硬盘柱面访问调度算法包括 FCFS、SSTF、SCAN、C-SCAN、LOOK、C-LOOK,并设计输入用例验证结果。

2 程序所涉及到的算法介绍以及相关实现函数

2.1 FIFO

2.1.1 介绍:

FCFS算法调度磁盘先服务于最先请求磁盘I/O的进程

2.1.2 程序中该算法的实现思路如下:

程序定义distance来记录磁头扫过的寻道距离,定义curCylinder来实时记录经过的柱面号,curCylinder按顺序依次被请求队列中的元素赋值,表示当前的磁头依次扫过请求队列中的柱面,满足了先来先服务的原则,磁头的移位,distance都加上前一个结点和下一个结点的距离,过程中不断打印curCylinder的值表示磁头扫过的路径,最后打印distance的值表示总的寻道距离。

2.1.3 算法代码以及详细注释如下:

/*先来先服务调度算法FCFS*/
void FCFS_alg(){
	int distance=0;
	int j,i,curCylinder;
	printf("请输入当前的的柱面号: ");
	scanf("%d",&curCylinder);
	printf("依次经过的柱面为:\n");
	//打印依次经过的柱面号,curCylinder记录实时经过的柱面号
	for(i=0;i<CylindReqNum;i++){
		printf("%d ",curCylinder);
		distance+=abs(curCylinder-CylindReqList[i]);//移动一次的距离
		curCylinder=CylindReqList[i];
	}
	printf("%d ",curCylinder);
	printf("\n总寻道距离:%d\n",distance);
}

2.2 SSTF

2.2.1 介绍:

该算法使得磁盘优先服务于要求访问的磁道与当前磁头所在的磁道距离最近的进程

2.2.2 程序中该算法的实现思路如下:

程序定义distance来记录磁头扫过的寻道距离,定义curCylinder来实时记录经过的柱面号,对请求序列数组中的柱面号进行排序,便于找到距离当前磁头指向柱面号最近的请求柱面,使用while循环对排序好的队列进行顺序查找,找到恰好比初始结点大的最近的请求柱面下标k,定义l=k-1即恰好比当前结点号小的最近的请求柱面下标,定义r=k即恰好比当前结点号大的最近的请求柱面下标。
采用归并的方法,左右比较找到距离当前结点号最近的请求柱面,当左边结点l距离当前结点号最近更近时,将curCylinder赋值为l下标指向的请求柱面,即将磁头往左移,同时将l减一,使得l继续作为恰好比当前结点号小的最近的请求柱面下标,当右边结点r距离当前结点号最近更近时,同理将curCylinder赋值为r,并把r加一,当l<0的时候,磁头只能往右移动,当r>=CylindReqNum,磁头事能往左移动,这样就时刻满足了SSTF的原则。
对于磁头的每次移位,distance都加上前一个结点和下一个结点的距离,过程中不断打印curCylinder的值表示磁头扫过的路径,最后打印distance的值表示总的寻道距离。

2.2.3 算法代码以及详细注释如下:

/*最短寻道时间优先调度算法SSTF*/
void SSTF_alg(){
	int curCylinder;
	int i,j;
	int distance=0;
	//排序
	qsort(CylindReqList,CylindReqNum,sizeof(int),cmp); 
	printf("请输入当前柱面号: ");
	scanf("%d",&curCylinder);
	printf("依次经过的柱面为:\n");
	int k=0;//记录恰好比初始结点大的最近的请求柱面
	while(k<CylindReqNum&&CylindReqList[k]<curCylinder){
    	k++;
	}
	int l=k-1;//记录恰好比当前结点号小的最近的请求柱面
	int r=k;//记录恰好比当前结点号大的最近的请求柱面
	//采用归并的方法,左右比较找到当前结点号最近的请求柱面
	while((l>=0)&&(r<CylindReqNum)){
		if((curCylinder-CylindReqList[l])<=(CylindReqList[r]-curCylinder)){
			printf("%d ",curCylinder);
			distance+=(curCylinder-CylindReqList[l]);
			curCylinder=CylindReqList[l];
			l=l-1;
		}
		else{
			printf("%d ",curCylinder);
			distance+=(CylindReqList[r]-curCylinder);
			curCylinder=CylindReqList[r];
			r=r+1;
		}
	}
	while(l>=0){
        printf("%d ",curCylinder);
        distance+=(curCylinder-CylindReqList[l]);
        curCylinder=CylindReqList[l];
        l=l-1;
	}
	while(r<CylindReqNum){
        printf("%d ",curCylinder);
        distance+=(CylindReqList[r]-curCylinder);
        curCylinder=CylindReqList[r];
        r=r+1;
	}
	printf("%d ",curCylinder);
	printf("\n总寻道距离:%d\n",distance);
}

2.3 SCAN

2.3.1 介绍:

磁盘臂从圆盘的一端开始向圆盘移动,另一端,当它到达有请求服务的柱面时则为其服务,直到它到达磁盘的另一端,在那里磁头运动反向并继续回来为有请求服务的柱面服务,直到没有请求为止。

2.3.2 程序中该算法的实现思路如下:

程序定义distance来记录磁头扫过的寻道距离,定义curCylinder来实时记录经过的柱面号,对请求序列数组中的柱面号进行排序,便于“电梯式”的滑动访问,使用while循环对排序好的队列进行顺序查找,找到恰好比初始结点大的最近的请求柱面下标k,定义l=k-1即恰好比初始结点号小的最近的请求柱面下标,定义r=k即恰好比初始结点号大的最近的请求柱面下标。
选择磁盘臂要向内移动还是向外移动,若向内移动,按照SCAN算法,一开始磁头向内滑动一直滑动到磁盘的头部即0处,一路上响应请求服务的柱面,到达0处,磁头反向滑动,向外滑动,一路上服务请求的柱面,直到响应全部服务结束,向外移动同理。
对于磁头的每次移位,curCylinder的值都要更新,distance都加上前一个结点和下一个结点的距离,过程中不断打印curCylinder的值表示磁头扫过的路径,最后打印distance的值表示总的寻道距离。

2.3.3 算法代码以及详细注释如下:

/*电梯算法一SCAN*/
void SCAN_alg(){
	int curCylinder,direction;
	int i,j,distance=0;
	//排序
	qsort(CylindReqList,CylindReqNum,sizeof(int),cmp); 
	printf("请输入当前柱面号: ");
	scanf("%d",&curCylinder);
	int k=0;//记录恰好比初始结点大的最近的请求柱面
	while(k<CylindReqNum&&CylindReqList[k]<curCylinder){
		k++;
	}
	int l=k-1;//记录恰好比初始结点小的最近的请求柱面
	int r=k;//记录恰好比初始结点大的最近的请求柱面
	printf("请输入当前移动臂的移动方向(0表示向内,1表示向外):");
	scanf("%d",&direction);
	printf("依次经过的柱面为:\n");
	if(direction==0){//向内开始滑动
		//按照SCAN算法,一开始磁头向内滑动,一路上响应请求服务的柱面
		for(j=l;j>=0;j--){
			printf("%d ",curCylinder);
			distance+=(curCylinder-CylindReqList[j]);
			curCylinder=CylindReqList[j];
		}
		//磁头一直滑动到磁盘的头部即0处
		if(CylindReqList[0]!=0){
			printf("%d ",curCylinder);
			distance+=(curCylinder-0);
			curCylinder=0;
		}
		//磁头反向滑动,向外滑动,一路上服务请求的柱面,直到响应全部服务结束
		for(j=r;j<CylindReqNum;j++){
			printf("%d ",curCylinder);
			distance+=(CylindReqList[j]-curCylinder);
			curCylinder=CylindReqList[j];
		}
		printf("%d ",curCylinder);
	}
	else{//向外开始滑动
		//按照SCAN算法,一开始磁头向外滑动,一路上响应请求服务的柱面
		for(j=r;j<CylindReqNum;j++){
			printf("%d ",curCylinder);
			distance+=(CylindReqList[j]-curCylinder);
			curCylinder=CylindReqList[j];
		}
		//磁头一直滑动到磁盘的尾部即CylindReqNum-1处
		if(CylindReqList[CylindReqNum-1]!=CylindNum-1){
			printf("%d ",curCylinder);
			distance+=(CylindNum-1-curCylinder);
			curCylinder=CylindNum-1;
		}
		//磁头反向滑动,向内滑动,一路上服务请求的柱面,直到响应全部服务结束
		for(j=l;j>=0;j--){
			printf("%d ",curCylinder);
			distance+=(curCylinder-CylindReqList[j]);
			curCylinder=CylindReqList[j];
		}
		printf("%d ",curCylinder);
	}
	printf("\n总寻道距离:%d\n",distance);
}

2.4 C-SCAN

2.4.1 介绍:

SCAN 的一种变体,与 SCAN 一样,C-SCAN 移动从磁盘的一端到另一端,一路上完成请求的服务。不同的是,当头部到达另一端时,它立即返回到磁盘的开头,无需对回程时的任何请求提供服务,再重新从磁盘的一断出发,直到完成所有的剩余请求。

2.4.2 程序中该算法的实现思路如下:

程序定义distance来记录磁头扫过的寻道距离,定义curCylinder来实时记录经过的柱面号,对请求序列数组中的柱面号进行排序,便于“电梯式”的滑动访问,使用while循环对排序好的队列进行顺序查找,找到恰好比初始结点大的最近的请求柱面下标k,定义l=k-1即恰好比初始结点号小的最近的请求柱面下标,定义r=k即恰好比初始结点号大的最近的请求柱面下标。
选择磁盘臂要向内移动还是向外移动,若向内移动,按照C-SCAN算法,一开始磁头向内滑动,一路上响应请求服务的柱面,磁头一直滑动到磁盘的头部即0处,接着磁头反向滑动,向外滑动,一直滑动到磁盘的尾部即CylindReqNum-1处,一路上不响应请求的服务,最后磁头再次反向滑动,向内滑动,一路上服务请求的柱面,直到响应全部服务结束,向外移动同理。
对于磁头的每次移位,curCylinder的值都要更新,distance都加上前一个结点和下一个结点的距离,过程中不断打印curCylinder的值表示磁头扫过的路径,最后打印distance的值表示总的寻道距离。

2.4.3 算法代码以及详细注释如下:

/*电梯算法二CSCAN*/
void CSCAN_alg(){
	int curCylinder,direction;
	int i,j,distance=0;
	//排序
	qsort(CylindReqList,CylindReqNum,sizeof(int),cmp); 
	printf("请输入当前柱面号: ");
	scanf("%d",&curCylinder);
	int k=0;//记录恰好比初始结点大的最近的请求柱面
	while(k<CylindReqNum&&CylindReqList[k]<curCylinder){
		k++;
	}
	int l=k-1;//记录恰好比初始结点小的最近的请求柱面
	int r=k;//记录恰好比初始结点大的最近的请求柱面
	printf("请输入当前移动臂的移动方向(0表示向内,1表示向外):");
	scanf("%d",&direction);
	printf("依次经过的柱面为:\n");
	if(direction==0){//向内开始滑动
		//按照C-SCAN算法,一开始磁头向内滑动,一路上响应请求服务的柱面
		for(j=l;j>=0;j--){
			printf("%d ",curCylinder);
			distance+=(curCylinder-CylindReqList[j]);
			curCylinder=CylindReqList[j];
		}
		//磁头一直滑动到磁盘的头部即0处
		if(CylindReqList[0]!=0){
			printf("%d ",curCylinder);
			distance+=(curCylinder-0);
			curCylinder=0;
		}
		//磁头反向滑动,向外滑动,一直滑动到磁盘的尾部即CylindReqNum-1处,一路上不响应请求的服务
		if(CylindReqList[CylindReqNum-1]!=curCylinder-1){
			printf("%d ",curCylinder);
			distance+=(CylindNum-1-curCylinder);
			curCylinder=CylindNum-1;
		}
		//磁头再次反向滑动,向内滑动,一路上服务请求的柱面,直到响应全部服务结束
		for(j=CylindReqNum-1;j>=r;j--){
			printf("%d ",curCylinder);
			distance+=(curCylinder-CylindReqList[j]);
			curCylinder=CylindReqList[j];
		}
		printf("%d ",curCylinder);
	}
	else{//向外开始滑动
		//按照C-SCAN算法,一开始磁头向外滑动,一路上响应请求服务的柱面
		for(j=r;j<CylindReqNum;j++){
			printf("%d ",curCylinder);
			distance+=(CylindReqList[j]-curCylinder);
			curCylinder=CylindReqList[j];
		}
		//磁头一直滑动到磁盘的尾部即CylindReqNum-1处
		if(CylindReqList[CylindReqNum-1]!=curCylinder-1){
			printf("%d ",curCylinder);
			distance+=(CylindNum-1-curCylinder);
			curCylinder=CylindNum-1;
		}
		//磁头反向滑动,向内滑动,一直滑动到磁盘的头部即0处,一路上不响应请求的服务
		if(CylindReqList[0]!=0){
			printf("%d ",curCylinder);
			distance+=(curCylinder-0);
			curCylinder=0;
		}
		//磁头再次反向滑动,向外滑动,一路上服务请求的柱面,直到响应全部服务结束
		for(j=0;j<=l;j++){
			printf("%d ",curCylinder);
			distance+=(CylindReqList[j]-curCylinder);
			curCylinder=CylindReqList[j];
		}
		printf("%d ",curCylinder);
	}
	printf("总寻道距离:%d\n",distance);
}

2.5 LOOK

2.5.1 介绍:

和SCAN类似,不同的是磁盘臂不是达到磁盘的另一端运动才反向,而是到达该方向的最后一个 I/O 请求的时候,运动就反向。

2.5.2 程序中该算法的实现思路如下:

程序定义distance来记录磁头扫过的寻道距离,定义curCylinder来实时记录经过的柱面号,对请求序列数组中的柱面号进行排序,便于“电梯式”的滑动访问,使用while循环对排序好的队列进行顺序查找,找到恰好比初始结点大的最近的请求柱面下标k,定义l=k-1即恰好比初始结点号小的最近的请求柱面下标,定义r=k即恰好比初始结点号大的最近的请求柱面下标。
选择磁盘臂要向内移动还是向外移动,若向内移动,按照LOOK算法,一开始磁头向内滑动,一路上响应请求服务的柱面,一直到该方向上的最后一个请求被响应,接着磁头反向滑动,向外滑动,一路上服务请求的柱面,直到响应全部服务结束,向外移动同理。
对于磁头的每次移位,curCylinder的值都要更新,distance都加上前一个结点和下一个结点的距离,过程中不断打印curCylinder的值表示磁头扫过的路径,最后打印distance的值表示总的寻道距离。

2.5.3 算法代码以及详细注释如下:

/*电梯算法三LOOK*/
void LOOK_alg(){
	int curCylinder,direction;
	int i,j,distance=0;
	//排序
	qsort(CylindReqList,CylindReqNum,sizeof(int),cmp); 
	printf("请输入当前柱面号: ");
	scanf("%d",&curCylinder);
	int k=0;//记录恰好比初始结点大的最近的请求柱面
	while(k<CylindReqNum&&CylindReqList[k]<curCylinder){
		k++;
	}
	int l=k-1;//记录恰好比初始结点小的最近的请求柱面
	int r=k;//记录恰好比初始结点大的最近的请求柱面
	printf("请输入当前移动臂的移动方向(0表示向内,1表示向外):");
	scanf("%d",&direction);
	printf("依次经过的柱面为:\n");
	if(direction==0){//向内开始滑动
		//按照LOOK算法,一开始磁头向内滑动,一路上响应请求服务的柱面,一直到该方向上的最后一个请求被响应
		for(j=l;j>=0;j--){
			printf("%d ",curCylinder);
			distance+=(curCylinder-CylindReqList[j]);
			curCylinder=CylindReqList[j];
		}
		//磁头反向滑动,向外滑动,一路上服务请求的柱面,直到响应全部服务结束
		for(j=r;j<CylindReqNum;j++){
			printf("%d ",curCylinder);
			distance+=(CylindReqList[j]-curCylinder);
			curCylinder=CylindReqList[j];
		}
		printf("%d ",curCylinder);
	}
	else{//向外开始滑动
		//按照LOOK算法,一开始磁头向外滑动,一路上响应请求服务的柱面,一直到该方向上的最后一个请求被响应
		for(j=r;j<CylindReqNum;j++){
			printf("%d ",curCylinder);
			distance+=(CylindReqList[j]-curCylinder);
			curCylinder=CylindReqList[j];
		}
		//磁头反向滑动,向内滑动,一路上服务请求的柱面,直到响应全部服务结束
		for(j=l;j>=0;j--){
			printf("%d ",curCylinder);
			distance+=(curCylinder-CylindReqList[j]);
			curCylinder=CylindReqList[j];
		}
		printf("%d ",curCylinder);
	}
	printf("总寻道距离:%d\n",distance);
}

2.6 C-LOOK

2.6.1 介绍:

和C-SCAN类似,不同的是磁盘臂不是达到磁盘的另一端运动才反向,而是到达该方向的最后一个 I/O 请求的时候,运动就反向。

2.6.2 程序中该算法的实现思路如下:

程序定义distance来记录磁头扫过的寻道距离,定义curCylinder来实时记录经过的柱面号,对请求序列数组中的柱面号进行排序,便于“电梯式”的滑动访问,使用while循环对排序好的队列进行顺序查找,找到恰好比初始结点大的最近的请求柱面下标k,定义l=k-1即恰好比初始结点号小的最近的请求柱面下标,定义r=k即恰好比初始结点号大的最近的请求柱面下标。
选择磁盘臂要向内移动还是向外移动,若向内移动,按照C-LOOK算法,一开始磁头向内滑动,一路上响应请求服务的柱面,一直到该方向上的最后一个请求的位置,接着磁头反向滑动,向外滑动,一直滑动到该方向上的最后一个请求的位置,一路上不响应请求的服务,最后磁头再次反向滑动,向内滑动,一路上响应请求的服务,直到响应全部服务结束,向外移动同理。
对于磁头的每次移位,curCylinder的值都要更新,distance都加上前一个结点和下一个结点的距离,过程中不断打印curCylinder的值表示磁头扫过的路径,最后打印distance的值表示总的寻道距离。

2.6.3 算法代码以及详细注释如下:

/*电梯算法四CLOOK*/
void CLOOK_alg(){
	int curCylinder,direction;
	int i,j,distance=0;
	//排序
	qsort(CylindReqList,CylindReqNum,sizeof(int),cmp); 
	printf("请输入当前柱面号: ");
	scanf("%d",&curCylinder);
	int k=0;//记录恰好比初始结点大的最近的请求柱面
	while(k<CylindReqNum&&CylindReqList[k]<curCylinder){
		k++;
	}
	int l=k-1;//记录恰好比初始结点小的最近的请求柱面
	int r=k;//记录恰好比初始结点大的最近的请求柱面
	printf("请输入当前移动臂的移动方向(0表示向内,1表示向外):");
	scanf("%d",&direction);
	printf("依次经过的柱面为:\n");
	if(direction==0){//向内开始滑动
		//按照C-LOOK算法,一开始磁头向内滑动,一路上响应请求服务的柱面,一直到该方向上的最后一个请求的位置
		for(j=l;j>=0;j--){
			printf("%d ",curCylinder);
			distance+=(curCylinder-CylindReqList[j]);
			curCylinder=CylindReqList[j];
		}
		//磁头反向滑动,向外滑动,一直滑动到该方向上的最后一个请求的位置,一路上不响应请求的服务
		if(r<=CylindReqNum-1){
			printf("%d ",curCylinder);
			distance+=(CylindReqList[CylindReqNum-1]-curCylinder);
			curCylinder=CylindReqList[CylindReqNum-1];
		}
		//磁头再次反向滑动,向内滑动,一路上响应请求的服务,直到响应全部服务结束
		for(j=CylindReqNum-2;j>=r;j--){
			printf("%d ",curCylinder);
			distance+=(curCylinder-CylindReqList[j]);
			curCylinder=CylindReqList[j];
		}
		printf("%d ",curCylinder);
	}
	else{//向外开始滑动
		//按照C-LOOK算法,一开始磁头向外滑动,一路上响应请求服务的柱面,一直到该方向上的最后一个请求的位置
		for(j=r;j<CylindReqNum;j++){
			printf("%d ",curCylinder);
			distance+=(CylindReqList[j]-curCylinder);
			curCylinder=CylindReqList[j];
		}
		//磁头反向滑动,向内滑动,一直滑动到该方向上的最后一个请求的位置,一路上不响应请求的服务
		if(l>=0){
			printf("%d ",curCylinder);
			distance+=(curCylinder-CylindReqList[0]);
			curCylinder=CylindReqList[0];
		}
		//磁头再次反向滑动,向外滑动,一路上响应请求的服务,直到响应全部服务结束
		for(j=1;j<=l;j++){
			printf("%d ",curCylinder);
			distance+=(CylindReqList[j]-curCylinder);
			curCylinder=CylindReqList[j];
		}
		printf("%d ",curCylinder);
	}
	printf("总寻道距离:%d\n",distance);
}

3 主函数解释以及输入输出说明:

3.1 主函数解释

程序文字提示用户输入初始的变量,如模拟硬盘的柱面个数,请求到达的柱面个数,请求到达的柱面序列,柱面访问调度算法,使用switch结果来实现调用用户选择的策略函数。

3.2 输入输出说明:

  • 输入: 按照程序的文字说明输入需要的初始值;
  • 输出: 输出在指定的柱面访问调度算法下,程度调度后的请求柱面序列(磁头滑动的路线),以及完成所有请求后的总寻道距离。

4 运行结果分析。

4.1 测试FIFO算法

使用课件上的样例,选择模拟硬盘的柱面个数为200个,即磁头再200个柱面之内移动,设置请求访问的柱面个数为8个,依次为98,183,37,122,14,124,65,67,选择算法为FIFO,设置初始磁头位置在柱面53中,那么它首先从53移到98,接着再到183、37、122、14、124、65,最后到67,磁头移动柱面的总数为640,执行结果如下图:

请添加图片描述

可以观察到该结果与分析的结果一致,且与课件结果图(如下)一致:

请添加图片描述

4.2 测试SSTF算法

使用课件上的样例,选择模拟硬盘的柱面个数为200个,即磁头再200个柱面之内移动,设置请求访问的柱面个数为8个,依次为98,183,37,122,14,124,65,67,选择算法为SSTF,设置初始磁头位置在柱面53中,与开始磁头位置(53)的最近请求位于柱面65,因此磁头移动到柱面65处,一旦位于柱面65,下个最近请求位于柱面67。当磁头移动到柱面67时候,由于柱面37比98还要近,所以下次处理37。如此,会处理位于柱面14的请求,接着处理98,122,124,最后处理183。

请添加图片描述

可以观察到该结果与分析的结果一致,且与课件结果图(如下)一致:

请添加图片描述

4.3 测试SCAN算法

使用课件上的样例,选择模拟硬盘的柱面个数为200个,即磁头再200个柱面之内移动,设置请求访问的柱面个数为8个,依次为98,183,37,122,14,124,65,67,选择算法为SCAN,设置初始磁头位置在柱面53中,磁头朝0移动,因此磁头接下来处理的是对于柱面37的请求,然后是14,当磁头位于柱面0时,磁头会反转,移向磁盘的另一端,并处理柱面65、67、98、122、124、183上的请求。

请添加图片描述

可以观察到该结果与分析的结果一致,且与课件结果图(如下)一致:

请添加图片描述

4.4 测试C-SCAN算法

使用课件上的样例,选择模拟硬盘的柱面个数为200个,即磁头再200个柱面之内移动,设置请求访问的柱面个数为8个,依次为98,183,37,122,14,124,65,67,选择算法为C-SCAN,设置初始磁头位置在柱面53中,磁头朝外移动,因此磁头接下来处理的是对于柱面65的请求,然后是67,98,122,124,183,当磁头位于柱面199时,磁头会反转,它立即返回到磁盘的开头0处,而并不处理任何回程上的请求,磁头再重新朝外移动,并处理剩余的请求,即柱面14,37上的请求。

请添加图片描述

可以观察到该结果与分析的结果一致,且与课件结果图(如下)一致:

请添加图片描述

4.5 测试LOOK算法

使用课件上的样例,选择模拟硬盘的柱面个数为200个,即磁头再200个柱面之内移动,设置请求访问的柱面个数为8个,依次为98,183,37,122,14,124,65,67,选择算法为LOOK,设置初始磁头位置在柱面53中,磁头朝0移动,因此磁头接下来处理的是对于柱面37的请求,然后是14,当磁头位于该方向上的最后一个请求位于的柱面14时,磁头会反转,移向磁盘的另一端,并处理柱面65、67、98、122、124、183上的请求。

请添加图片描述

可以观察到该结果与分析的结果一致,且与课件结果图(如下)一致:

请添加图片描述

4.5 测试C-LOOK算法

使用课件上的样例,选择模拟硬盘的柱面个数为200个,即磁头再200个柱面之内移动,设置请求访问的柱面个数为8个,依次为98,183,37,122,14,124,65,67,选择算法为C-LOOK,设置初始磁头位置在柱面53中,磁头朝外移动,因此磁头接下来处理的是对于柱面65的请求,然后是67,98,122,124,183,当磁头位于该方向上最后一个请求位于的柱面183时,磁头会反转,它立即返回到返回方向上的第一个请求14处,而并不处理任何回程上的请求,磁头再重新朝外移动,并处理剩余的请求,即柱面14,37上的请求。

请添加图片描述

可以观察到该结果与分析的结果一致,且与课件结果图(如下)一致:

请添加图片描述

5 完整代码

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
// FCFS、SSTF、SCAN、C-SCAN、LOOK、C-LOOK
#define FCFS 1
#define SSTF 2
#define SCAN 3
#define C_SCAN 4
#define LOOK 5
#define C_LOOK 6
#define MAX_SIZE 100

int CylindNum;                //模拟硬盘的柱面个数
int CylindReqList[MAX_SIZE];  //请求访问的柱面序列
int CylindReqNum;             //请求访问的柱面个数
int cmp(const void* a, const void* b) { return *(int*)a - *(int*)b; }
/*先来先服务调度算法FCFS*/
void FCFS_alg() {
    int distance = 0;
    int j, i, curCylinder;
    printf("请输入当前的的柱面号: ");
    scanf("%d", &curCylinder);
    printf("依次经过的柱面为:\n");
    //打印依次经过的柱面号,curCylinder记录实时经过的柱面号
    for (i = 0; i < CylindReqNum; i++) {
        printf("%d ", curCylinder);
        distance += abs(curCylinder - CylindReqList[i]);  //移动一次的距离
        curCylinder = CylindReqList[i];
    }
    printf("%d ", curCylinder);
    printf("\n总寻道距离:%d\n", distance);
}
/*最短寻道时间优先调度算法SSTF*/
void SSTF_alg() {
    int curCylinder;
    int i, j;
    int distance = 0;
    //排序
    qsort(CylindReqList, CylindReqNum, sizeof(int), cmp);
    printf("请输入当前柱面号: ");
    scanf("%d", &curCylinder);
    printf("依次经过的柱面为:\n");
    int k = 0;  //记录恰好比初始结点大的最近的请求柱面下标
    while (k < CylindReqNum && CylindReqList[k] < curCylinder) {
        k++;
    }
    int l = k - 1;  //记录恰好比当前结点号小的最近的请求柱面
    int r = k;      //记录恰好比当前结点号大的最近的请求柱面
    //采用归并的方法,左右比较找到当前结点号最近的请求柱面
    while ((l >= 0) && (r < CylindReqNum)) {
        if ((curCylinder - CylindReqList[l]) <=
            (CylindReqList[r] - curCylinder)) {
            printf("%d ", curCylinder);
            distance += (curCylinder - CylindReqList[l]);
            curCylinder = CylindReqList[l];
            l = l - 1;
        } else {
            printf("%d ", curCylinder);
            distance += (CylindReqList[r] - curCylinder);
            curCylinder = CylindReqList[r];
            r = r + 1;
        }
    }
    while (l >= 0) {
        printf("%d ", curCylinder);
        distance += (curCylinder - CylindReqList[l]);
        curCylinder = CylindReqList[l];
        l = l - 1;
    }
    while (r < CylindReqNum) {
        printf("%d ", curCylinder);
        distance += (CylindReqList[r] - curCylinder);
        curCylinder = CylindReqList[r];
        r = r + 1;
    }
    printf("%d ", curCylinder);
    printf("\n总寻道距离:%d\n", distance);
}
/*电梯算法一SCAN*/
void SCAN_alg() {
    int curCylinder, direction;
    int i, j, distance = 0;
    //排序
    qsort(CylindReqList, CylindReqNum, sizeof(int), cmp);
    printf("请输入当前柱面号: ");
    scanf("%d", &curCylinder);
    int k = 0;  //记录恰好比初始结点大的最近的请求柱面
    while (k < CylindReqNum && CylindReqList[k] < curCylinder) {
        k++;
    }
    int l = k - 1;  //记录恰好比初始结点小的最近的请求柱面
    int r = k;      //记录恰好比初始结点大的最近的请求柱面
    printf("请输入当前移动臂的移动方向(0表示向内,1表示向外):");
    scanf("%d", &direction);
    printf("依次经过的柱面为:\n");
    if (direction == 0) {  //向内开始滑动
        //按照SCAN算法,一开始磁头向内滑动,一路上响应请求服务的柱面
        for (j = l; j >= 0; j--) {
            printf("%d ", curCylinder);
            distance += (curCylinder - CylindReqList[j]);
            curCylinder = CylindReqList[j];
        }
        //磁头一直滑动到磁盘的头部即0处
        if (CylindReqList[0] != 0) {
            printf("%d ", curCylinder);
            distance += (curCylinder - 0);
            curCylinder = 0;
        }
        //磁头反向滑动,向外滑动,一路上服务请求的柱面,直到响应全部服务结束
        for (j = r; j < CylindReqNum; j++) {
            printf("%d ", curCylinder);
            distance += (CylindReqList[j] - curCylinder);
            curCylinder = CylindReqList[j];
        }
        printf("%d ", curCylinder);
    } else {  //向外开始滑动
        //按照SCAN算法,一开始磁头向外滑动,一路上响应请求服务的柱面
        for (j = r; j < CylindReqNum; j++) {
            printf("%d ", curCylinder);
            distance += (CylindReqList[j] - curCylinder);
            curCylinder = CylindReqList[j];
        }
        //磁头一直滑动到磁盘的尾部即CylindReqNum-1处
        if (CylindReqList[CylindReqNum - 1] != CylindNum - 1) {
            printf("%d ", curCylinder);
            distance += (CylindNum - 1 - curCylinder);
            curCylinder = CylindNum - 1;
        }
        //磁头反向滑动,向内滑动,一路上服务请求的柱面,直到响应全部服务结束
        for (j = l; j >= 0; j--) {
            printf("%d ", curCylinder);
            distance += (curCylinder - CylindReqList[j]);
            curCylinder = CylindReqList[j];
        }
        printf("%d ", curCylinder);
    }
    printf("\n总寻道距离:%d\n", distance);
}
/*电梯算法二CSCAN*/
void CSCAN_alg() {
    int curCylinder, direction;
    int i, j, distance = 0;
    //排序
    qsort(CylindReqList, CylindReqNum, sizeof(int), cmp);
    printf("请输入当前柱面号: ");
    scanf("%d", &curCylinder);
    int k = 0;  //记录恰好比初始结点大的最近的请求柱面
    while (k < CylindReqNum && CylindReqList[k] < curCylinder) {
        k++;
    }
    int l = k - 1;  //记录恰好比初始结点小的最近的请求柱面
    int r = k;      //记录恰好比初始结点大的最近的请求柱面
    printf("请输入当前移动臂的移动方向(0表示向内,1表示向外):");
    scanf("%d", &direction);
    printf("依次经过的柱面为:\n");
    if (direction == 0) {  //向内开始滑动
        //按照C-SCAN算法,一开始磁头向内滑动,一路上响应请求服务的柱面
        for (j = l; j >= 0; j--) {
            printf("%d ", curCylinder);
            distance += (curCylinder - CylindReqList[j]);
            curCylinder = CylindReqList[j];
        }
        //磁头一直滑动到磁盘的头部即0处
        if (CylindReqList[0] != 0) {
            printf("%d ", curCylinder);
            distance += (curCylinder - 0);
            curCylinder = 0;
        }
        //磁头反向滑动,向外滑动,一直滑动到磁盘的尾部即CylindReqNum-1处,一路上不响应请求的服务
        if (CylindReqList[CylindReqNum - 1] != curCylinder - 1) {
            printf("%d ", curCylinder);
            distance += (CylindNum - 1 - curCylinder);
            curCylinder = CylindNum - 1;
        }
        //磁头再次反向滑动,向内滑动,一路上服务请求的柱面,直到响应全部服务结束
        for (j = CylindReqNum - 1; j >= r; j--) {
            printf("%d ", curCylinder);
            distance += (curCylinder - CylindReqList[j]);
            curCylinder = CylindReqList[j];
        }
        printf("%d ", curCylinder);
    } else {  //向外开始滑动
        //按照C-SCAN算法,一开始磁头向外滑动,一路上响应请求服务的柱面
        for (j = r; j < CylindReqNum; j++) {
            printf("%d ", curCylinder);
            distance += (CylindReqList[j] - curCylinder);
            curCylinder = CylindReqList[j];
        }
        //磁头一直滑动到磁盘的尾部即CylindReqNum-1处
        if (CylindReqList[CylindReqNum - 1] != curCylinder - 1) {
            printf("%d ", curCylinder);
            distance += (CylindNum - 1 - curCylinder);
            curCylinder = CylindNum - 1;
        }
        //磁头反向滑动,向内滑动,一直滑动到磁盘的头部即0处,一路上不响应请求的服务
        if (CylindReqList[0] != 0) {
            printf("%d ", curCylinder);
            distance += (curCylinder - 0);
            curCylinder = 0;
        }
        //磁头再次反向滑动,向外滑动,一路上服务请求的柱面,直到响应全部服务结束
        for (j = 0; j <= l; j++) {
            printf("%d ", curCylinder);
            distance += (CylindReqList[j] - curCylinder);
            curCylinder = CylindReqList[j];
        }
        printf("%d ", curCylinder);
    }
    printf("总寻道距离:%d\n", distance);
}
/*电梯算法三LOOK*/
void LOOK_alg() {
    int curCylinder, direction;
    int i, j, distance = 0;
    //排序
    qsort(CylindReqList, CylindReqNum, sizeof(int), cmp);
    printf("请输入当前柱面号: ");
    scanf("%d", &curCylinder);
    int k = 0;  //记录恰好比初始结点大的最近的请求柱面
    while (k < CylindReqNum && CylindReqList[k] < curCylinder) {
        k++;
    }
    int l = k - 1;  //记录恰好比初始结点小的最近的请求柱面
    int r = k;      //记录恰好比初始结点大的最近的请求柱面
    printf("请输入当前移动臂的移动方向(0表示向内,1表示向外):");
    scanf("%d", &direction);
    printf("依次经过的柱面为:\n");
    if (direction == 0) {  //向内开始滑动
        //按照LOOK算法,一开始磁头向内滑动,一路上响应请求服务的柱面,一直到该方向上的最后一个请求被响应
        for (j = l; j >= 0; j--) {
            printf("%d ", curCylinder);
            distance += (curCylinder - CylindReqList[j]);
            curCylinder = CylindReqList[j];
        }
        //磁头反向滑动,向外滑动,一路上服务请求的柱面,直到响应全部服务结束
        for (j = r; j < CylindReqNum; j++) {
            printf("%d ", curCylinder);
            distance += (CylindReqList[j] - curCylinder);
            curCylinder = CylindReqList[j];
        }
        printf("%d ", curCylinder);
    } else {  //向外开始滑动
        //按照LOOK算法,一开始磁头向外滑动,一路上响应请求服务的柱面,一直到该方向上的最后一个请求被响应
        for (j = r; j < CylindReqNum; j++) {
            printf("%d ", curCylinder);
            distance += (CylindReqList[j] - curCylinder);
            curCylinder = CylindReqList[j];
        }
        //磁头反向滑动,向内滑动,一路上服务请求的柱面,直到响应全部服务结束
        for (j = l; j >= 0; j--) {
            printf("%d ", curCylinder);
            distance += (curCylinder - CylindReqList[j]);
            curCylinder = CylindReqList[j];
        }
        printf("%d ", curCylinder);
    }
    printf("总寻道距离:%d\n", distance);
}
/*电梯算法四CLOOK*/
void CLOOK_alg() {
    int curCylinder, direction;
    int i, j, distance = 0;
    //排序
    qsort(CylindReqList, CylindReqNum, sizeof(int), cmp);
    printf("请输入当前柱面号: ");
    scanf("%d", &curCylinder);
    int k = 0;  //记录恰好比初始结点大的最近的请求柱面
    while (k < CylindReqNum && CylindReqList[k] < curCylinder) {
        k++;
    }
    int l = k - 1;  //记录恰好比初始结点小的最近的请求柱面
    int r = k;      //记录恰好比初始结点大的最近的请求柱面
    printf("请输入当前移动臂的移动方向(0表示向内,1表示向外):");
    scanf("%d", &direction);
    printf("依次经过的柱面为:\n");
    if (direction == 0) {  //向内开始滑动
        //按照C-LOOK算法,一开始磁头向内滑动,一路上响应请求服务的柱面,一直到该方向上的最后一个请求的位置
        for (j = l; j >= 0; j--) {
            printf("%d ", curCylinder);
            distance += (curCylinder - CylindReqList[j]);
            curCylinder = CylindReqList[j];
        }
        //磁头反向滑动,向外滑动,一直滑动到该方向上的最后一个请求的位置,一路上不响应请求的服务
        if (r <= CylindReqNum - 1) {
            printf("%d ", curCylinder);
            distance += (CylindReqList[CylindReqNum - 1] - curCylinder);
            curCylinder = CylindReqList[CylindReqNum - 1];
        }
        //磁头再次反向滑动,向内滑动,一路上响应请求的服务,直到响应全部服务结束
        for (j = CylindReqNum - 2; j >= r; j--) {
            printf("%d ", curCylinder);
            distance += (curCylinder - CylindReqList[j]);
            curCylinder = CylindReqList[j];
        }
        printf("%d ", curCylinder);
    } else {  //向外开始滑动
        //按照C-LOOK算法,一开始磁头向外滑动,一路上响应请求服务的柱面,一直到该方向上的最后一个请求的位置
        for (j = r; j < CylindReqNum; j++) {
            printf("%d ", curCylinder);
            distance += (CylindReqList[j] - curCylinder);
            curCylinder = CylindReqList[j];
        }
        //磁头反向滑动,向内滑动,一直滑动到该方向上的最后一个请求的位置,一路上不响应请求的服务
        if (l >= 0) {
            printf("%d ", curCylinder);
            distance += (curCylinder - CylindReqList[0]);
            curCylinder = CylindReqList[0];
        }
        //磁头再次反向滑动,向外滑动,一路上响应请求的服务,直到响应全部服务结束
        for (j = 1; j <= l; j++) {
            printf("%d ", curCylinder);
            distance += (CylindReqList[j] - curCylinder);
            curCylinder = CylindReqList[j];
        }
        printf("%d ", curCylinder);
    }
    printf("总寻道距离:%d\n", distance);
}
void main() {
    //输入初始信息
    int strategy;
    int i;
    printf("请输入模拟硬盘的柱面个数: ");
    scanf("%d", &CylindNum);
    printf("请输入请求到达的柱面个数: ");
    scanf("%d", &CylindReqNum);
    printf("请输入请求到达的柱面序列: ");
    for (i = 0; i < CylindReqNum; i++) {
        scanf("%d", &CylindReqList[i]);
    }
    printf("1.FCFS\n2.SSTF\n3.SCAN\n4.C_SCAN\n5.LOOK\n6.C_LOOK\n");
    printf("请选择硬盘柱面访问调度算法:\n");
    scanf("%d", &strategy);
    if (strategy > 6 || strategy < 1) {  //策略选择不合法
        printf("illegal strategy!");
        return;
    }
    //选择柱面访问调度算法
    switch (strategy) {
            // FCFS、SSTF、SCAN、C_SCAN、LOOK、C_LOOK
        case FCFS:
            FCFS_alg();
            break;
        case SSTF:
            SSTF_alg();
            break;
        case SCAN:
            SCAN_alg();
            break;
        case C_SCAN:
            CSCAN_alg();
            break;
        case LOOK:
            LOOK_alg();
            break;
        case C_LOOK:
            CLOOK_alg();
            break;
        default:
            break;
    }
}
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-25 16:12:38  更:2021-07-25 16:12:49 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/4 13:11:11-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码