操作系统课程设计报告磁盘调度算法
操作系统实验之处理机调度实验报告

操作系统实验之处理机调度实验报告一、实验目的处理机调度是操作系统中的核心功能之一,本次实验的主要目的是通过模拟不同的处理机调度算法,深入理解操作系统对处理机资源的分配和管理策略,比较不同调度算法的性能差异,并观察它们在不同负载情况下的表现。
二、实验环境本次实验使用的操作系统为 Windows 10,编程语言为 Python 38。
实验中使用了 Python 的相关库,如`numpy`、`matplotlib`等,用于数据生成、计算和图形绘制。
三、实验原理1、先来先服务(FCFS)调度算法先来先服务算法按照作业到达的先后顺序进行调度。
先到达的作业先被服务,直到完成或阻塞,然后再处理下一个到达的作业。
2、短作业优先(SJF)调度算法短作业优先算法选择预计运行时间最短的作业先执行。
这种算法可以有效地减少作业的平均等待时间,但可能导致长作业长时间等待。
3、时间片轮转(RR)调度算法时间片轮转算法将处理机的时间分成固定长度的时间片,每个作业轮流获得一个时间片的处理时间。
当时间片用完后,如果作业还未完成,则将其放入就绪队列的末尾等待下一轮调度。
4、优先级调度算法优先级调度算法为每个作业分配一个优先级,优先级高的作业先被执行。
优先级可以根据作业的性质、紧急程度等因素来确定。
四、实验内容与步骤1、数据生成首先,生成一组模拟的作业,包括作业的到达时间、预计运行时间和优先级等信息。
为了使实验结果更具代表性,生成了不同规模和特征的作业集合。
2、算法实现分别实现了先来先服务、短作业优先、时间片轮转和优先级调度这四种算法。
在实现过程中,严格按照算法的定义和规则进行处理机的分配和调度。
3、性能评估指标定义了以下性能评估指标来比较不同调度算法的效果:平均等待时间:作业在就绪队列中的等待时间的平均值。
平均周转时间:作业从到达系统到完成的时间间隔的平均值。
系统吞吐量:单位时间内完成的作业数量。
4、实验结果分析对每种调度算法进行多次实验,使用不同的作业集合,并记录相应的性能指标数据。
分时操作系统调度算法

分时操作系统调度算法分时操作系统采用时间片轮转的方式为用户提供服务,那么你了解什么是时间片轮转调度吗?下面由店铺为大家整理了分时操作系统的调度算法的相关知识,希望对大家有帮助!分时操作系统的调度算法详解时间片的概念,可以用来部分解释本书开始时的一句话:"在数据传输领域,你亲眼看见的,都不是真的"。
在宏观上:我们可以同时打开多个应用程序,每个程序并行不悖,同时运行。
但是在微观上:由于只有一个CPU,一次只能处理程序要求的一部分,如何处理公平,一种方法就是引入时间片,每个程序轮流执行。
概念的引入说到并行计算,尤其是单台计算机的并行计算,一定要先建立时间片的概念。
我们现在所用的,不管是Windows还是Linux,一般都称为多任务操作系统,即,系统允许并行运行多个应用程序。
操作系统一般是按照一定策略,定期给每个活动的进程执行其内部程序的机会,并且每次只执行一小段时间,然后操作系统利用中断强行退出执行,将当前程序信息压栈,然后开始执行下一个进程的一小段程序。
通过这样不断快速的循环切换,每个程序都获得执行,在用户看来,感觉到很多程序都在平行的执行,这就模拟了并行计算。
当然,新的多核CPU以及超线程CPU,内部就有超过1个的CPU执行体,运行时就不是模拟了,而是真的有两个以上的程序在被执行。
当然在我们程序员看来,只需要理解程序是被操作系统片段执行的,每个片段就是一个时间片,就足够了。
既然是片段执行,程序员就必须理解,在自己的程序运行时不是独一无二的,我们看似很顺畅的工作,其实是由一个个的执行片段构成的,我们眼中相邻的两条语句甚至同一个语句中两个不同的运算符之间,都有可能插入其他线程或进程的动作。
基本概念时间片轮转法(Round-Robin,RR)主要用于分时系统中的进程调度。
为了实现轮转调度,系统把所有就绪进程按先入先出的原则排成一个队列。
新来的进程加到就绪队列末尾。
每当执行进程调度时,进程调度程序总是选出就绪队列的队首进程,让它在CPU上运行一个时间片的时间。
进程调度算法实验报告

计算机操作系统实验报告实验二进程调度算法一、实验名称:进程调度算法二、实验内容:编程实现如下算法:1.先来先服务算法;2.短进程优先算法;3.时间片轮转调度算法。
三、问题分析与设计:1.先来先服务调度算法先来先服务调度算法是一种最简单的调度算法,该算法既可以用于作业调度,也可用于进程调度。
当在作业调度中采用该算法时,每次调度都是从后备作业队列中选择一个或多个最先进入该队列的作业,将他们调入内存,为它们分配资源、创建进程,然后放入就绪队列。
在进程调度中采用FCFS算法时,则每次调度是从就绪队列中选择一个最先进入该队列的进程,为之分配处理机,使之投入运行。
该进程一直运行到完成或发生某事件而阻塞后才放弃处理机。
FCFS算法比较有利于长作业(进程),2.短作业(进程)优先调度算法短作业(进程)优先调度算法SJ(P)F,是指对短作业或短进程优先调度的算法。
它们可以分别用于作业调度和进程调度。
短作业优先(SJF)的调度算法是从后备队列中选择一个或若干个估计运行时间最短的作业,将它们调入内存运行。
而短进程(SPF)调度算法则是从就绪队列中选出一个估计运行时间最短的进程,将处理机分配给它,使它立即执行并一直执行到完成,或发生某事件而被阻塞放弃处理机再重新调度。
SJ(P)F调度算法能有效地降低作业(进程)的平均等待时间,提高系统吞吐量。
该算法对长作业不利,完全未考虑作业的紧迫程度。
3.时间片轮转算法在时间片轮转算法中,系统将所有的就绪进程按先来先服务的原则排成一个队列,每次调度时,把CPU分配给队首进程,并令其执行一个时间片。
当执行的时间片用完时,由一个计数器发出时钟中断请求,调度程序便据此信号来停止该进程的执行,并将它送往就绪队列的末尾;然后,再把处理机分配给就绪队列中新的队首进程,同时也让它执行一个时间片。
这样就可以保证就绪队列中的所有进程在一给定的时间内均能获得一时间片的处理机执行时间。
换言之,系统能在给定的时间内响应所有用户的请求。
操作系统时间片轮转算法与优先级调度算法

操作系统时间片轮转算法与优先级调度算法操作系统作为计算机的核心,需要负责管理和分配系统资源的功能。
其中,调度算法是操作系统中非常重要的一个功能,它决定了如何分配CPU时间,因此直接影响系统的性能和响应速度。
本文将介绍两种操作系统中常用的调度算法:时间片轮转算法和优先级调度算法。
时间片轮转算法时间片轮转算法(Round Robin)是一种基本的调度算法,它是多道程序设计中常用的一种算法。
在内存中同时存放多个进程,并根据每个进程的优先级轮流分配 CPU 时间,以保证每个进程都能得到一定的CPU时间片,从而保证操作系统的公平性和系统的稳定性。
基本思想时间片轮转算法的基本思想是:将每个进程分配相同长度的CPU时间片,一旦时间片用完,立即将该进程挂起,并将 CPU 分配给下一个进程。
这样就可以保证每个进程都有相同的机会获得 CPU 时间,避免了某个进程长时间霸占CPU而导致其他进程无法运行的情况。
算法流程时间片轮转算法的具体实现过程如下:1.将所有待运行的进程加入到就绪队列中;2.从就绪队列中取出第一个进程,将其运行指定时间片长度的时间;3.如果该进程在运行时间片结束之前自己退出,那么直接将其从就绪队列中取出,释放资源;4.如果该进程在运行时间片结束之前没有自己退出,那么将其挂起放到队列的尾部,然后将 CPU 分配给下一个进程,重复2-4步骤,直到所有进程执行完毕。
算法优点时间片轮转算法的优点如下:1.公平:每个进程都能得到相同长度的时间片,避免了某个进程长时间霸占CPU的情况,从而保证了每个进程都会运行;2.适用:时间片轮转算法适用于多任务并发的环境下,可以有效地避免死锁和饥饿现象;3.高效:时间片轮转算法可以保证 CPU 的高效利用,能够最大限度地提高 CPU 的性能。
算法缺点时间片轮转算法的缺点如下:1.精度问题:时间片长度不能太长,否则会导致某些进程长时间等待CPU时间片;2.资源浪费:如果一个进程只需要很短的时间就可以完成任务,但由于时间片的限制而占用CPU的时间,这就是一种资源浪费。
进程调度算法实验报告

操作系统实验报告(二)实验题目:进程调度算法实验环境:C++实验目的:编程模拟实现几种常见的进程调度算法,通过对几组进程分别使用不同的调度算法,计算进程的平均周转时间和平均带权周转时间,比较各种算法的性能优劣。
实验内容:编程实现如下算法:1.先来先服务算法;2.短进程优先算法;3.时间片轮转调度算法。
设计分析:程序流程图:1.先来先服务算法2.短进程优先算法3.时间片轮转调度算法实验代码:1.先来先服务算法#include <iostream.h>#define n 20typedef struct{int id; //进程名int atime; //进程到达时间int runtime; //进程运行时间}fcs;void main(){int amount,i,j,diao,huan;fcs f[n];cout<<"请输入进程个数:"<<endl;cin>>amount;for(i=0;i<amount;i++){cout<<"请输入进程名,进程到达时间,进程运行时间:"<<endl; cin>>f[i].id;cin>>f[i].atime;cin>>f[i].runtime;}for(i=0;i<amount;i++) //按进程到达时间的先后排序{ //如果两个进程同时到达,按在屏幕先输入的先运行for(j=0;j<amount-i-1;j++){ if(f[j].atime>f[j+1].atime){diao=f[j].atime;f[j].atime=f[j+1].atime;f[j+1].atime=diao;huan=f[j].id;f[j].id=f[j+1].id;f[j+1].id=huan;}}}for(i=0;i<amount;i++){cout<<"进程:"<<f[i].id<<"从"<<f[i].atime<<"开始"<<","<<"在"<<f[i].atime+f[i].runtime<<"之前结束。
操作系统中的调度算法分析

操作系统中的调度算法分析操作系统是计算机系统中最为重要的组成部分之一,它负责管理计算机系统的资源,包括硬件和软件资源,并且为其它应用程序提供支持和服务。
在操作系统中,调度算法是其中非常重要的一部分,对于它的优化和改进有着非常重要的意义。
本文将按照类别对操作系统中的调度算法进行详细分析,包括批处理系统中的调度算法、交互式系统中的调度算法、实时系统中的调度算法,以及多处理器系统中的调度算法。
一、批处理系统中的调度算法批处理系统是指能够自动地运行一批作业的操作系统,它是在没有任何人的干预下完成作业的自动化系统。
在批处理系统中的调度算法,其主要目的是使各作业的吞吐率最大,并且减少响应时间和等待时间。
在批处理系统中的调度算法包括先来先服务(FCFS)算法、短进程优先(SJF)算法、最高响应比优先(HRRN)算法等。
1、先来先服务(FCFS)算法先来先服务算法,也称为先到先服务算法,是最简单的一种调度算法。
它的作用是按照进程的到达时间的先后顺序进行服务,先到达的进程先得到服务,后到达的进程则必须等待前面进程的服务结束才能够被执行。
优点是公平、简单,缺点是会导致长作业等待时间长,短作业等待时间短。
2、短进程优先(SJF)算法短进程优先算法,是按照进程的执行时间长度来排序,执行时间越短的进程优先得到服务,它可以使得等待时间总和最小,从而提高系统的吞吐率。
但是,如果遇到长作业,则会导致短作业等待时间过长。
3、最高响应比优先(HRRN)算法最高响应比优先算法,则是综合考虑前两种算法的优点而得到的一种调度算法,它会计算出每个进程的响应比,并且选择响应比最高的进程进行执行。
响应比的计算公式是:响应比 = (等待时间 + 执行时间) / 执行时间该算法可以最大限度地减少等待时间,并且适用于长作业与短作业的服务。
二、交互式系统中的调度算法相比于批处理系统,交互式系统强调用户体验,需要快速响应用户的指令请求。
因此,交互式系统中的调度算法,其主要目的是降低响应时间,尽可能快地处理用户的请求。
操作系统典型调度算法
操作系统典型调度算法在操作系统中存在多种调度算法,下⾯介绍⼏种常⽤的调度算法。
先来先服务(FCFS)调度算法FCFS调度算法是⼀种最简单的调度算法,FCFS调度算法每次从就绪队列中选择最先进⼊该队列的进程,将处理机分配给它,使之投⼊运⾏,直到完成或因某种原因⽽阻塞时才释放处理机。
下⾯通过⼀个实例来说明FCFS调度算法的性能。
假设系统中有4个作业,它们的提交时间分别是8、8.4、8.8、9,运⾏时间依次是2、1、0.5、0.2,系统⾤⽤FCFS调度算法,这组作业的平均等待时间、平均周转时间和平均带权周转时间见表2-3。
表2-3 FCFS调度算法的性能作业号提交时间运⾏时间开始时间等待时间完成时间周转时间带权周转时间18280102128.4110 1.611 2.6 2.638.80.511 2.211.5 2.7 5.4490.211.5 2.511.7 2.713.5平均等待时间 t = (0+1.6+2.2+2.5)/4=1.575平均周转时间 T = (2+2.6+2.7+2.7)/4=2.5平均带权周转时间 W = (1+2.6+5.牡13.5)/4=5.625FCFS调度算法属于不可剥夺算法。
从表⾯上看,它对所有作业都是公平的,但若⼀个长作业先到达系统,就会使后⾯许多短作业等待很长时间,因此它不能作为分时系统和实时系统的主要调度策略。
但它常被结合在其他调度策略中使⽤。
例如,在使⽤优先级作为调度策略的系统中,往往对多个具有相同优先级的进程按FCFS原则处理。
FCFS调度算法的特点是算法简单,但效率低;对长作业⽐较有利,但对短作业不利(相对SJF和⾼响应⽐);有利于CPU繁忙型作业,⽽不利于I/O繁忙型作业。
短作业优先(SJF)调度算法短作业(进程)优先调度算法是指对短作业(进程)优先调度的算法。
短作业优先(SJF)调度算法是从后备队列中选择⼀个或若⼲个估计运⾏时间最短的作业,将它们调⼊内存运⾏。
《操作系统》课程实验报告
《操作系统》课程实验报告一、实验目的本次《操作系统》课程实验的主要目的是通过实际操作和观察,深入理解操作系统的工作原理、进程管理、内存管理、文件系统等核心概念,并掌握相关的操作技能和分析方法。
二、实验环境1、操作系统:Windows 10 专业版2、开发工具:Visual Studio Code3、编程语言:C/C++三、实验内容(一)进程管理实验1、进程创建与终止通过编程实现创建新进程,并观察进程的创建过程和资源分配情况。
同时,实现进程的正常终止和异常终止,并分析其对系统的影响。
2、进程同步与互斥使用信号量、互斥锁等机制实现进程之间的同步与互斥。
通过模拟多个进程对共享资源的访问,观察并解决可能出现的竞争条件和死锁问题。
(二)内存管理实验1、内存分配与回收实现不同的内存分配算法,如首次适应算法、最佳适应算法和最坏适应算法。
观察在不同的内存请求序列下,内存的分配和回收情况,并分析算法的性能和优缺点。
2、虚拟内存管理研究虚拟内存的工作原理,通过设置页面大小、页表结构等参数,观察页面的换入换出过程,以及对系统性能的影响。
(三)文件系统实验1、文件操作实现文件的创建、打开、读取、写入、关闭等基本操作。
观察文件在磁盘上的存储方式和文件系统的目录结构。
2、文件系统性能优化研究文件系统的缓存机制、磁盘调度算法等,通过对大量文件的读写操作,评估不同优化策略对文件系统性能的提升效果。
四、实验步骤(一)进程管理实验步骤1、进程创建与终止(1)使用 C/C++语言编写程序,调用系统函数创建新进程。
(2)在子进程中执行特定的任务,父进程等待子进程结束,并获取子进程的返回值。
(3)通过设置异常情况,模拟子进程的异常终止,观察父进程的处理方式。
2、进程同步与互斥(1)定义共享资源和相关的信号量或互斥锁。
(2)创建多个进程,模拟对共享资源的并发访问。
(3)在访问共享资源的关键代码段使用同步机制,确保进程之间的正确协作。
(4)观察并分析在不同的并发情况下,系统的运行结果和资源竞争情况。
操作系统综合性实验报告-进程调度(含代码)
int count;
// 记录进程执行的次数
struct node *next;
// 队列指针
}PCB;
PCB *ready=NULL,*run=NULL,*finish=NULL; // 和完成队列
定义三个队列, 就绪队列, 执 行队列
int num; void GetFirst(); void Output(); void InsertTime(PCB *in); void InsertFinish(PCB *in); TimeCreate(); void RoundRun(); void main() {
三、实验内容
1. 用 C 语言(或其它语言,如 Java )编程实现对 N 个进程采用某种进程调度算
法(如动态优先权调度算法、先来先服务算法、短进程优先算法、时间片轮转调度
算法)调度执行的模拟。
2. 每个用来标识进程的进程控制块 typedef struct node {
PCB 可用结构来描述,包括以下字段:
一个时间片,当执行完时,有一个计时器发出时钟中断请求,该进程停止,并被送
到就绪队列的末尾,然后再把处理机分配就绪队列的队列进程,同时也让它执行一
个时间片。 ( 3 )、通过亲手实验, 对上述写的时间片的工作流程和原理有了更贴切的认识。
另外本次实验遇到了很大的麻烦,其实大部分代码是借鉴网上的,但自己通过修改, 来获取自己想要的,在自己的努力和同学的帮助下终于调试正确,很是高兴。
void InsertTime(PCB *in)
// 将进程插入到就绪队列尾部
{ PCB *fst; fst = ready;
if(ready == NULL) {
in->next = ready; ready = in; } else { while(fst->next != NULL) {
ssd 磁盘分配算法
ssd 磁盘分配算法
SSD(固态硬盘)磁盘分配算法是指在使用SSD时,操作系统如何有效地管理和分配磁盘空间以提高性能和寿命。
SSD磁盘分配算法的设计考虑了SSD的特性和限制,以及用户的需求。
以下是几种常见的SSD磁盘分配算法:
1. 块级分配算法,SSD通常以块为单位进行读写操作。
块级分配算法会将数据分成固定大小的块,并将这些块分配到SSD上。
这种算法的优点是简单高效,但可能会导致空间碎片和浪费。
2. 页面级分配算法,SSD内部存储单元是页面,页面级分配算法会以页面为单位进行数据的管理和分配。
这种算法可以更好地利用SSD的空间,减少空间碎片,但需要更复杂的管理。
3. 热数据识别算法,SSD磁盘分配算法也可以根据数据的热度来进行分配。
热数据是指频繁访问的数据,可以通过热数据识别算法将其存储在性能更高的区域,以提高访问速度。
4. 垃圾回收算法,由于SSD的特性,写入操作可能会导致垃圾数据产生,影响性能。
因此,SSD磁盘分配算法中的垃圾回收算法
非常重要,它可以及时清理垃圾数据,提高SSD的性能和寿命。
总的来说,SSD磁盘分配算法的设计需要兼顾性能、空间利用率和寿命等多个方面。
不同的应用场景和SSD硬件特性可能需要不同的磁盘分配算法来进行优化。
同时,随着技术的发展,新的SSD 磁盘分配算法也在不断涌现,以满足不断变化的需求。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
课程设计课程设计名称:操作系统应用课程设计专业班级:学生姓名:xxxxx学号:指导教师:课程设计时间: 2010.12.20-2010.12.26计算机科学专业课程设计任务书说明:本表由指导教师填写,由教研室主任审核后下达给选题学生,装订在设计(论文)首页一 .课程设计需求分析操作系统是计算机系统的一个重要系统软件。
我们在本课程的实验过程中,了解实际操作系统的工作过程,在实践中加深对操作系统原理的理解。
磁盘存储器不仅容量大,存取速度快,而且可以实现随机存取,是当前存放大量程序和数据的理想设备,故在现代计算机系统中,都配置了磁盘存储器,并以它为主来存放文件。
这样,对文件的操作,都将涉及到对磁盘的访问。
磁盘I/O速度的高低和磁盘系统的可靠性都将直接影响到系统性能。
因此,设法改善磁盘系统的性能,已成为现代操作系统的重要任务之一。
磁盘性能有数据的组织、磁盘的类型和访问时间等。
磁盘调度的目标是使磁盘的平均寻道时间最少。
也正因为这样,我们有必要对各算法进行模拟,进而比较、分析、了解。
本实验设计的目的是通过设计一个磁盘调度模拟系统,以加深对最短寻道时间优先(SSTF)、N步扫描算法(NStepSCAN)等磁盘调度算法的理解。
让我们更好地掌握操作系统的原理及实现方法,加深对操作系统基础理论和重要算法的理解,加强动手能力。
二.课程设计原理设备的动态分配算法与进程调度相似,也是基于一定的分配策略的。
常用的分配策略有先请求先分配、优先级高者先分配等策略。
在多道程序系统中,低效率通常是由于磁盘类旋转设备使用不当造成的。
操作系统中,对磁盘的访问要求来自多方面,常常需要排队。
这时,对众多的访问要求按一定的次序响应,会直接影响磁盘的工作效率,进而影响系统的性能。
访问磁盘的时间因子由3部分构成,它们是查找(查找磁道)时间、等待(旋转等待扇区)时间和数据传输时间,其中查找时间是决定因素。
因此,磁盘调度算法先考虑优化查找策略,需要时再优化旋转等待策略。
平均寻道长度(L)为所有磁道所需移动距离之和除以总的所需访问的磁道数(N),即:L=(M1+M2+……+Mi+……+MN)/N。
其中Mi为所需访问的磁道号所需移动的磁道数。
启动磁盘执行输入输出操作时,要把移动臂移动到指定的柱面,再等待指定扇区的旋转到磁头位置下,然后让指定的磁头进行读写,完成信息传送。
因此,执行一次输入输出所花的时间有:寻找时间——磁头在移动臂带动下移动到指定柱面所花的时间;延迟时间——指定扇区旋转到磁头下所需的时间;传送时间——由磁头进程读写完成信息传送的时间。
其中传送信息所花的时间,是在硬件设计就固定的。
而寻找时间和延迟时间是与信息在磁盘上的位置有关。
为了减少移动臂进行移动花费的时间,每个文件的信息不是按盘面上的磁道顺序存放满一个盘面后,再放到下一个盘面上。
而是按柱面存放,同一柱面上的各磁道被放满信息后,再放到下一个柱面上。
所以各磁盘的编号按柱面顺序(从0号柱面开始),每个柱面按磁道顺序,每个磁道又按扇区顺序进行排序。
磁盘是可供多个进程共享的设备,当有多个进程都要求访问磁盘是,应采用一种最佳调度算法,以使各种进程对磁盘的平均访问时间最小。
由于在访问磁盘的时间中,主要是寻道时间,因此,磁盘调度的目标,是使磁盘的平均寻道时间最少。
三.算法分析及程序概要设计1.最短寻道时间优先算法(SSTF)1.1算法分析:最短寻找时间优先调度算法总是从等待访问者中挑选寻找时间最短的那个请求先执行的,而不管访问者到来的先后次序。
也就是说,该算法选择这样的进程:其要求访问的磁道与当前磁头所在的磁道距离最近,以使每次的寻道时间最短。
但这种算法不能保证平均寻道时间最短。
现在利用一个例子来讨论,假设当前移动臂所在的磁道为100,进程请求访问磁盘的先后次序为:55、58、39、18、90、160、150、38、184。
那么该算法将这样进行进程调度:现在当100号柱面的操作结束后,应该先处理90号柱面的请求,然后到达58号柱面执行操作,随后处理55号柱面请求,后继操作的次序应该是39、38、18、150、160、184。
采用最短寻找时间优先算法决定等待访问者执行操作的次序时,读写磁头总共移动了200多个柱面的距离,与先来先服务、算法比较,大幅度地减少了寻找时间,因而缩短了为各访问者请求服务的平均时间,也就提高了系统效率。
SSTF算法虽然能获得较好的寻道性能,但却可能导致某个进程发生“饥饿”(Starvation)现象。
因为只要不断有新进程的请求到达,且其所要访问的磁道与磁头当前所在磁道的距离较近,这种新进程的I/O请求必然优先满足。
也就是说,SSTF查找模式有高度局部化的倾向,会推迟一些请求的服务,甚至引起无限拖延(饥饿)。
1.2概要设计(流程图):2、NStepSCAN算法2.1算法分析N步扫描算法是基于扫描算法发展而成的,故要想很好的了解它,首先得对扫描算法加以理解分析,只有这样才能很好地理解N步扫描算法。
扫描算法(SCAN)又称电梯调度算法。
该算法不仅考虑到与访问的磁道与当前磁道间的距离,更优先考虑的是磁头当前的移动方向。
SCAN算法是磁头前进方向上的最短查找时间优先算法,它排除了磁头在盘面局部位置上的往复移动,SCAN算法这种逐步自里向外又自外向里(或先自外向里又自外向里)的磁头移动规率,很好地避免了出现“饥饿”现象,并在很大程度上消除了SSTF算法的不公平性,但仍有利于对中间磁道的请求。
“电梯调度”算法是从移动臂当前位置开始沿着臂的移动方向去选择离当前移动臂最近的那个柱访问者,如果沿臂的移动方向无请求访问时,就改变臂的移动方向再选择。
这好比乘电梯,如果电梯已向上运动到4层时,依次有3位乘客陈生、伍生、张生在等候乘电梯。
他们的要求是:陈生在2层等待去10层;伍生在5层等待去底层;张生在8层等待15层。
由于电梯目前运动方向是向上,所以电梯的形成是先把乘客张生从8层带到15层,然后电梯换成下行方向,把乘客伍生从5层带到底层,电梯最后再调换方向,把乘客陈生从2层送到10层。
但是,“电梯调度”算法在实现时,不仅要记住读写磁头的当前位置,还必须记住移动臂的当前前进方向。
N步扫描算法是将磁盘请求队列分成若干个长度为N的子队列,磁盘调度将按FCFS算法依次处理这些子队列。
而没处理一个队列时又是按SCAN算法,对一个队列处理完后,在处理其他队列。
当正在处理某子队列时,如果又出现新的I/O请求,便将新请求进程放入其他队列,这样就可以避免出现粘着现象,统称“磁盘粘着”(Armstickiness)(有一个或几个进程对某一磁道有较高的访问频率,即这些进程反复请求对某一磁道的I/O操作,从而垄断了整个磁盘设备的现象)。
而在SSTF、SCAN及CSCAN几种调度算法中,都有可能出现磁臂留在某处不动的情况,即出现磁盘粘着现象。
当N取值很大时,会使N步扫描的性能接近于SCAN算法的性能;当N=1时,N步扫描算法退化为FCFS算法。
此外,需要了解的是N步SCAN算法的简化算法是FSCAN算法,即将磁盘请求队列分成两个子队列的算法。
2.2概要设计(流程图)四、详细设计#include"stdio.h"#include"stdlib.h"//#include"iostream.h"#define maxsize 100 //定义最大数组域int now,s;//最短寻道时间优先调度算法void SSTF(int array[],int m){int temp;int k=1;int now,l,r; //当前磁道号now;找出的当前磁道左侧的磁道l,右侧的磁道rint i,j,sum=0;int avg;for(i=0;i<m;i++){for(j=i+1;j<m;j++)//对磁道号进行从小到大排列{if(array[i]>array[j])//两磁道号之间比较{temp=array[i];array[i]=array[j];array[j]=temp;}}}for( i=0;i<m;i++)//输出排序后的磁道号数组{printf("%d ",array[i]);}printf("\n 请输入当前的磁道号:");scanf("%d",&now);printf("\n SSTF调度结果: ");if(array[m-1]<=now)//判断整个数组里的数是否都小于当前磁道号{for(i=m-1;i>=0;i--)//将数组磁道号从大到小输出printf("%d ",array[i]);sum=now-array[0];//计算移动距离}else if(array[0]>=now)//判断整个数组里的数是否都大于当前磁道号{for(i=0;i<m;i++)//将磁道号从小到大输出printf("%d ",array[i]);sum=array[m-1]-now;//计算移动距离}else{while(array[k]<now)//逐一比较以确定K值{k++;}l=k-1;r=k;//确定当前磁道在已排的序列中的位置while((l>=0)&&(r<m)){if((now-array[l])<=(array[r]-now))//判断最短距离{printf("%d ",array[l]);sum+=now-array[l];//计算移动距离now=array[l];l=l-1;}else{printf("%d ",array[r]);sum+=array[r]-now;//计算移动距离now=array[r];r=r+1;}}if(l==-1){for(j=r;j<m;j++){printf("%d ",array[j]);}sum+=array[m-1]-array[0];//计算移动距离}else{for(j=l;j>=0;j--){printf("%d ",array[j]);}sum+=array[m-1]-array[0];//计算移动距离}}avg=sum/m;printf("\n 移动的总道数: %d \n",sum);printf(" 平均寻道长度: %d \n",avg);}//扫描调度方法void SCAN(int array[],int m,int d)//先要给出当前磁道号和移动臂的移动方向{int k=1;int l,r;int i,j,sum=0;int avg;int temp; //用于排序的临时参数int q;for(i=0;i<m;i++){for(j=i+1;j<m;j++){if(array[i]>array[j])//对磁道号进行从小到大排列{temp=array[i];array[i]=array[j];array[j]=temp;}}}if(array[m-1]<=now)//判断整个数组里的数是否都小于当前磁道号{printf("\n SCAN调度结果: ");for(i=m-1;i>=0;i--){printf("%d ",array[i]);//将数组磁道号从大到小输出q=array[i];}sum=now-q;//计算移动距离s=s+sum;now=q;}else if(array[0]>=now)//判断整个数组里的数是否都大于当前磁道号{printf("\n SCAN调度结果: ");for(i=0;i<m;i++){printf("%d ",array[i]);//将磁道号从小到大输出q=array[i];}sum=array[m-1]-now;//计算移动距离s=s+sum;now=q;}else{while(array[k]<now)//逐一比较以确定K值{k++;}l=k-1;r=k;printf("\n SCAN调度结果: ");if(d==0){for(j=l;j>=0;j--){printf("%d ",array[j]);q=array[j];}for(j=r;j<m;j++){printf("%d ",array[j]);q=array[j];}sum=now-2*array[0]+array[m-1];//计算移动距离 s=s+sum;now=q;}//磁道号减小方向else{for(j=r;j<m;j++){printf("%d ",array[j]);q=array[j];}for(j=l;j>=0;j--){printf("%d ",array[j]);q=array[j];}sum=-now-array[0]+2*array[m-1];//计算移动距离s=s+sum;now=q;}//磁道号增加方向}avg=sum/m;printf("\n 该子队列移动的总道数: %d \n",sum);printf(" 该子队列平均寻道长度: %d \n",avg);}void NStepSCAN(int array[],int m){int sn,N,d; //sn标记每一子队列的长度,N记录子队列个数,now标记当前磁道号int b[100],c[100]; //b[100]储存前几个子队列,c[100]储存最后一个子队列int i=0,j=0,k=0,n=1;int ave;printf("请输入当前磁道号:\n");scanf("%d",&now);printf("请输入子队列的个数:\n");scanf("%d",&N);while(N<1||N>m){printf("超出范围,文件中的磁道数不够分组,请重新输入:\n"); scanf("%d",&N);}printf("请输入当前移动臂的移动的方向 (1 磁道号增加方向,0磁道号减小方向) : ");scanf("%d",&d);sn=m/N;while(N!=1) //当不是最后一个子队列时,循环进行SCAN调度{j=0;for(i=k;i<sn*n;i=k,j++){b[j]=array[i];k=k+1;}printf("\n第%d个队列的排序结果为:\n",n);SCAN(b,sn,d);N=N-1;n=n+1;}if(N==1) //最后一个子队列时进行SCAN调度{for(i=k,j=0;i<m;i++,j++){c[j]=array[i];}printf("\n最后一个队列的调度结果为:\n"); SCAN(c,m-k,d);}ave=s/m;printf("\n该调度总的结果为:\n");printf("\n 移动的总道数: %d \n",s);printf(" 平均寻道长度: %d \n",ave);}// 操作界面int main(){int c;int C=1;FILE *fp;//定义指针文件int cidao[maxsize];//定义磁道号数组int i=0,count;fp=fopen("cidao.txt","r+");//读取cidao.txt文件if(fp==NULL)//判断文件是否存在{printf("\n 请先设置磁道! \n");exit(0);}while(!feof(fp))//如果磁道文件存在{fscanf(fp,"%d",&cidao[i]);//调入磁道号i++;}count=i;printf("\n --------------------------------------------------\n");printf(" 10-11年度OS课程设计--磁盘调度算法模拟");printf("\n --------------------------------------------------\n");printf("\n 磁道读取结果:\n");for(i=0;i<count;i++){printf("%5d",cidao[i]);//输出读取的磁道的磁道号}printf("\n ");while(C==1){printf(" ╭═══════════════╮\n");printf(" ║操作系统课程设计║\n");printf(" ╭═════┤磁盘调度算法├═════╮ \n ");printf(" ║║║║ \n");printf(" ║╰═══════════════╯║ \n");printf(" ║║ \n");printf(" ║ 1.最短寻道时间优先算法(SSTF) ║ \n");printf(" ║║ \n");printf(" ║║ \n");printf(" ║ 2.N步扫描算法(NStepScan) ║ \n");printf(" ║║ \n");printf(" ║║ \n");printf(" ║║ \n");printf(" ║╭───────────────────────╮║ \n");printf(" ╰═┤请输入你的选择的算法(输入0离开)├═╯ \n");printf(" ╰───────────────────────╯ \n");scanf("%d",&c);if(c==0) exit(0);printf(" ");while(c!=1&&c!=2){printf("输入数据超出范围,请重新输入您想进行的调度算法:\n");scanf("%d",&c);}switch(c){case 1:SSTF(cidao,count);//最短寻道时间优先算法printf("\n");break;case 2:i=0;fp=fopen("cidao.txt","r+");//读取cidao.txt文件 if(fp==NULL)//判断文件是否存在{printf("\n 请先设置磁道! \n");exit(0);}while(!feof(fp))//如果磁道文件存在{fscanf(fp,"%d",&cidao[i]);//调入磁道号i++;}count=i;printf("\n 磁道读取结果:\n");for(i=0;i<count;i++){printf("%5d",cidao[i]);//输出读取的磁道的磁道号}printf("\n ");NStepSCAN(cidao,count);//N步扫描算法printf("\n");break;}printf(" 是否继续(按0结束,按1继续)?");scanf("%5d",&C);}return(0);}五、调试运行结果1. 调试运行后的开始界面如下:2、调试运行各个算法结果如下:2.1运行最短寻道时间优先(SSTF)算法调度程序结果如下:2.2调试运行NStepSCAN调度程序结果如下:2.2.1移动臂的移动方向以磁道号增加方向:2.2.2移动臂的移动方向以磁道号减小方向:3.输入错误后程序界面如下:3.1在选择算法时,如果输入数字不在1-2之间,出错界面如下:3.2在进行N步扫描算法时,当输入要进行分组的子队列个数少于文件中的磁盘号数时,出现如下界面:七.调试分析及总结整个设计中最麻烦的就是整个程序模块的划分和各模块之间接口设计,编程中经常犯想当然的错误,编程中出现了不少奇怪的错误。