一、实验题目
磁盘调度算法的模拟与实现
二、实验目的
(1) 了解磁盘结构以及磁盘上数据的组织方式。
(2) 掌握磁盘访问时间的计算方式。
(3) 掌握常用磁盘调度算法及其相关特性。
三、总体设计(含背景知识或基本原理与算法、或模块介绍、设计步骤等)
共享设备的典型代表为磁盘,磁盘物理块的地址由柱面号、磁头号、扇区号来指定,完成磁盘某一个物理块的访问要经过三个阶段:寻道时间Ts、旋转延迟时间Tw和读写时间Trw。
寻道时间Ts是磁头从当前磁道移动到目标磁道所需要的时间;旋转延迟时间Tw是当磁头停留在目标磁道后,目标物理块从当前位置旋转到磁头位置的时间;读写时间Trw是目标物理块内容与内存中对应交换的时间。磁盘调度的原则是公平和高吞吐量,衡量指标有访问时间T和平均访问时间Ta:
T=Ts+Tw+Trw
Ta=Tsa+Twa+Trwa
寻道时间和旋转延迟时间成为调度算法的主要考虑因素。减少访问时间就是要减少寻道时间和旋转延迟时间。
(1)先来先服务算法(FCFS)First Come First Service
这是一种比较简单的磁盘调度算法。它根据进程请求访问磁盘的先后次序进行调度。此算法的优点是公平、简单,且每个进程的请求都能依次得到处理,不会出现某一进程的请求长期得不到满足的情况。此算法由于未对寻道进行优化,在对磁盘的访问请求比较多的情况下,此算法将降低设备服务的吞吐量,致使平均寻道时间可能较长,但各进程得到服务的响应时间的变化幅度较小。
(2)最短寻道时间优先算法(SSTF) Shortest Seek Time First
该算法选择这样的进程,其要求访问的磁道与当前磁头所在的磁道距离最近,以使每次的寻道时间最短,该算法可以得到比较好的吞吐量,但却不能保证平均寻道时间最短。其缺点是对用户的服务请求的响应机会不是均等的,因而导致响应时间的变化幅度很大。在服务请求很多的情况下,对内外边缘磁道的请求将会无限期的被延迟,有些请求的响应时间将不可预期。
(3)扫描算法(SCAN)电梯调度
扫描算法不仅考虑到欲访问的磁道与当前磁道的距离,更优先考虑的是磁头的当前移动方向。例如,当磁头正在自里向外移动时,扫描算法所选择的下一个访问对象应是其欲访问的磁道既在当前磁道之外,又是距离最近的。这样自里向外地访问,直到再无更外的磁道需要访问才将磁臂换向,自外向里移动。这时,同样也是每次选择这样的进程来调度,即其要访问的磁道,在当前磁道之内,从而避免了饥饿现象的出现。由于这种算法中磁头移动的规律颇似电梯的运行,故又称为电梯调度算法。此算法基本上克服了最短寻道时间优先算法的服务集中于中间磁道和响应时间变化比较大的缺点,而具有最短寻道时间优先算法的优点即吞吐量较大,平均响应时间较小,但由于是摆动式的扫描方法,两侧磁道被访问的频率仍低于中间磁道。
(4)循环扫描算法(C-SCAN)
在扫描算法的基础上规定磁头单向移动来提供服务,回返时直接快速移动至起始端而不服务任何请求。
四、详细设计(含主要的数据结构、程序流程图、关键代码等)
关键代码:
void FCFS()
{
printf("先来先服务 FCFS\n");
printf("被访问的下一个磁道\t\t\t磁道号移动距离\n");
int su=kai;
sum=0;
for(int i=0;i<num;i++)
{ if(su<s[i])
s1[i]=s[i]-su;
else
s1[i]=su-s[i];
su=s[i];
sum+=s1[i];
}
for(int i=0;i<num;i++)
{
printf("\t%d\t\t\t\t\t%d\t\t\n",s[i],s1[i]);
}
printf("寻道长度:%d\n",sum);
}
void SSTF()
{
printf("最短寻道 SSTF:\n");
printf("被访问的下一个磁道\t\t\t磁道号移动距离\n");
int su=kai;
int s2[100];
sum=0;
for(int i=0;i<m;i++)
s2[i]=c1[i];
for(int i=0;i<n;i++)
s2[i+m]=c2[i];
for(int i=0;i<num;i++)
{ if(su<s2[i])
s1[i]=s2[i]-su;
else
s1[i]=su-s2[i];
su=s2[i];
sum+=s1[i];
}
for(int i=0;i<num;i++)
{
printf("\t%d\t\t\t\t\t%d\t\t\n",s2[i],s1[i]);
}
printf("寻道长度:%d\n",sum);
}
void SCAN()
{
printf("扫描算法 SCAN:\n");
printf("被访问的下一个磁道:\t\t\t磁道号移动距离:\n");
int su=kai;
int s2[100];
sum=0;
for(int i=0;i<n;i++)
s2[i] =c2[i];
for(int i=0;i<m;i++)
s2[i+n]=c1[i];
for(int i=0;i<num;i++)
{ if(su<s2[i])
s1[i]=s2[i]-su;
else
s1[i]=su-s2[i];
su=s2[i];
sum+=s1[i];
}
for(int i=0;i<num;i++)
{
printf("\t%d\t\t\t\t\t%d\t\t\n",s2[i],s1[i]);
}
printf("寻道长度:%d\n",sum);
}
void CSAN()
{
printf("循环扫描 CSAN:\n");
printf("被访问的下一个磁道:\t\t\t磁道号移动距离:\n");
int su=kai;
int j=0;
int s2[100];
sum=0;
for(int i=0;i<n;i++)
s2[i] =c2[i];
for(int i=m-1;i>=0;j++,i--)
s2[j+n]=c1[i];
for(int i=0;i<num;i++)
{ if(su<s2[i])
s1[i]=s2[i]-su;
else
s1[i]=su-s2[i];
su=s2[i];
sum+=s1[i];
}
//sum=sum/num;
for(int i=0;i<num;i++)
{printf("\t%d\t\t\t\t\t%d\t\t\n",s2[i],s1[i]);
}
printf("寻道长度:%d\n",sum);
}
五、实验结果与分析
先是创建磁道:
>创建磁道后,选择算法,进行排序。并求出 被访问磁道顺序,磁道号移动距离,寻到长度。
六、小结与心得体会
这个实验实现了一个简单的磁盘调度算法模拟程序。它提供了以下功能:
创建磁道:用户可以输入磁道的起始位置、最长磁道号以及磁道的个数,并检查输入的合法性。
先来先服务(FCFS):按照请求的顺序依次访问磁道,计算磁道号移动距离和寻道长度。
最短寻道(SSTF):选择与当前磁头位置最近的磁道进行访问,计算磁道号移动距离和寻道长度。
扫描算法(SCAN):磁头从起始位置开始,依次向一个方向移动,直到最边界,然后改变方向,计算磁道号移动距离和寻道长度。
循环扫描算法(CSCAN):磁头从起始位置开始,依次向一个方向移动,直到最边界,然后回到起始位置,计算磁道号移动距离和寻道长度。
该程序实现了基本的磁盘调度算法,可以有效地模拟磁盘访问过程,并计算出寻道长度。
*不同的调度算法在不同的磁盘访问模式下可能会有不同的性能表现,可以通过多次测试和比较来选择合适的算法。
*代码实现较为简单,没有加入错误处理和异常情况的处理,可以进一步完善代码以提高程序的稳定性和健壮性。
*通过该程序的实现,可以更好地理解磁盘调度算法的原理和实际应用,对操作系统的磁盘管理有更深入的了解。