磁盘调度算法

磁盘调度在多道程序设计的计算机系统中,各个进程可能会不断提出不同的对磁盘进行读/写操作的请求。由于有时候这些进程的发送请求的速度比磁盘响应的还要快,因此我们有必要为每个磁盘设备建立一个等待队列,常用的磁盘调度算法有以下四种:

先来先服务算法(FCFS),

最短寻道时间优先算法(SSTF),

扫描算法(SCAN),

循环扫描算法(CSCAN)

 

例:假定某磁盘共有200个柱面,编号为0-199,如果在为访问143号柱面的请求者服务后,当前正在为访问125号柱面的请求服务,同时有若干请求者在等待服务,它们每次要访问的柱面号为   86,147,91,177,94,150,102,175,130

 

 

1、先来先服务算法(FCFS)First Come First Service

这是一种比较简单的磁盘调度算法。它根据进程请求访问磁盘的先后次序进行调度。此算法的优点是公平、简单,且每个进程的请求都能依次得到处理,不会出现某一进程的请求长期得不到满足的情况。此算法由于未对寻道进行优化,在对磁盘的访问请求比较多的情况下,此算法将降低设备服务的吞吐量,致使平均寻道时间可能较长,但各进程得到服务的响应时间的变化幅度较小。

先来先服务 (125)86.147.91.177.94.150.102.175.130

 

2、最短寻道时间优先算法(SSTF) Shortest Seek Time First

该算法选择这样的进程,其要求访问的磁道与当前磁头所在的磁道距离最近,以使每次的寻道时间最短,该算法可以得到比较好的吞吐量,但却不能保证平均寻道时间最短。其缺点是对用户的服务请求的响应机会不是均等的,因而导致响应时间的变化幅度很大。在服务请求很多的情况下,对内外边缘磁道的请求将会无限期的被延迟,有些请求的响应时间将不可预期。

最短寻道时间优先(125)130.147.150.175.177.102.94.91.86

 

3、扫描算法(SCAN)电梯调度

扫描算法不仅考虑到欲访问的磁道与当前磁道的距离,更优先考虑的是磁头的当前移动方向。例如,当磁头正在自里向外移动时,扫描算法所选择的下一个访问对象应是其欲访问的磁道既在当前磁道之外,又是距离最近的。这样自里向外地访问,直到再无更外的磁道需要访问才将磁臂换向,自外向里移动。这时,同样也是每次选择这样的进程来调度,即其要访问的磁道,在当前磁道之内,从而避免了饥饿现象的出现。由于这种算法中磁头移动的规律颇似电梯的运行,故又称为电梯调度算法。此算法基本上克服了最短寻道时间优先算法的服务集中于中间磁道和响应时间变化比较大的缺点,而具有最短寻道时间优先算法的优点即吞吐量较大,平均响应时间较小,但由于是摆动式的扫描方法,两侧磁道被访问的频率仍低于中间磁道。

电梯调度(125)102.94.91.86.130.147.150.175.177

 

4、循环扫描算法(CSCAN)

循环扫描算法是对扫描算法的改进。如果对磁道的访问请求是均匀分布的,当磁头到达磁盘的一端,并反向运动时落在磁头之后的访问请求相对较少。这是由于这些磁道刚被处理,而磁盘另一端的请求密度相当高,且这些访问请求等待的时间较长,为了解决这种情况,循环扫描算法规定磁头单向移动。例如,只自里向外移动,当磁头移到最外的被访问磁道时,磁头立即返回到最里的欲访磁道,即将最小磁道号紧接着最大磁道号构成循环,进行扫描。

循环扫描 (125)130.147.150.175.177.86.91.94.102

  1 package opp;
  2 
  3 import java.util.Arrays;
  4 import java.util.Scanner;
  5 import java.util.Stack;
  6 
  7 public class Main {
  8     public static boolean judge(String choice) {
  9         if (choice.matches("[0-4]")) {
 10             return true;
 11         }
 12         return false;
 13     }
 14 
 15     public static int Menu() {
 16         while (true) {
 17             System.out.println("=============================");
 18             System.out.println("           磁盘调度                   ");
 19             System.out.println("=============================");
 20             System.out.println("1.先来先服务");
 21             System.out.println("2.最短寻道时间优先");
 22             System.out.println("3.扫描算法");
 23             System.out.println("4.循环扫描算法");
 24             System.out.println("0.结束");
 25             System.out.println("=============================");
 26             Scanner cin = new Scanner(System.in);
 27             int num = cin.nextInt();
 28             if (judge(num + "") == false) {
 29                 System.out.println("您的输入有误,请重新输入!");
 30             } else {
 31                 return num;
 32             }
 33         }
 34 
 35     }
 36 
 37     public static void main(String[] args) {
 38         while (true) {
 39             int choice = Menu();
 40             switch (choice) {
 41             case 1: {
 42                 FCFS();
 43                 break;
 44             }
 45             case 2: {
 46                 SSTF();
 47                 break;
 48             }
 49             case 3: {
 50                 SCAN();
 51                 break;
 52             }
 53             case 4: {
 54                 CSCAN();
 55                 break;
 56             }
 57             default: {
 58                 break;
 59             }
 60             }
 61         }
 62 
 63     }
 64 
 65     private static void Input(int num[], int str[], int cur[]) {
 66         Scanner cin = new Scanner(System.in);
 67         System.out.println("输入磁道数:");
 68         num[0] = cin.nextInt();
 69         System.out.println("每个磁道:");
 70         for (int i = 0; i < num[0]; i++) {
 71             str[i] = cin.nextInt();
 72         }
 73         System.out.println("开始磁道:");
 74         cur[0] = cin.nextInt();
 75     }
 76 
 77     private static void CSCAN() {
 78         int[] num = new int[1];
 79         int[] cur = new int[1];
 80         int[] str = new int[1000];
 81         int[] dis = new int[1000];
 82         int[] next = new int[1000];
 83         Input(num, str, cur);
 84         int[] sum = new int[1];
 85 
 86         calFour(num[0], str, cur[0], next, sum, dis);
 87         Output(str, sum[0], dis, num[0]);
 88 
 89     }
 90 
 91     private static void calFour(int num, int[] str, int cur, int[] next, int[] sum, int[] dis) {
 92         for (int i = 0, len = str.length; i < len; i++) {
 93             if (str[i] == 0)
 94                 str[i] = 0x3f3f3f3f;
 95         }
 96         Arrays.sort(str);
 97         int[] vis = new int[num];
 98         int cnt = 0;
 99 
100         int curx = -1;
101         for (int i = 0; i < num; i++) {
102             if (str[i] >= cur && vis[i] == 0) {
103                 curx = i;
104                 break;
105             }
106 
107         }
108         for (int i = curx; i < num; i++) {
109             next[cnt++] = str[i];
110             dis[cnt - 1] = abs(cur - next[cnt - 1]);
111             sum[0] += abs(cur - next[cnt - 1]);
112             cur = str[i];
113         }
114         for (int i = 0; i < curx; i++) {
115             next[cnt++] = str[i];
116             dis[cnt - 1] = abs(cur - next[cnt - 1]);
117             sum[0] += abs(cur - next[cnt - 1]);
118             cur = str[i];
119         }
120 
121     }
122 
123     private static void Output(int[] str, int sum, int dis[], int num) {
124         System.out.println("下一个磁道  移动距离");
125         for (int i = 0; i < num; i++) {
126             System.out.println(str[i] + "    " + dis[i]);
127         }
128         System.out.println("平均寻道长度:" + sum / (num * 1.0));
129 
130     }
131 
132     private static int calOne(int str[], int dis[], int cur[]) {
133         int sum = 0;
134         for (int i = 0, num = str.length; i < num; i++) {
135 
136             dis[i] = abs(str[i] - cur[0]);
137 
138             sum += dis[i];
139 
140             cur[0] = str[i];
141         }
142         return sum;
143     }
144 
145     private static void SCAN() {
146         int[] num = new int[1];
147         int[] cur = new int[1];
148         int[] str = new int[1000];
149         int[] dis = new int[1000];
150         int[] next = new int[1000];
151         Input(num, str, cur);
152         int[] sum = new int[1];
153         calThree(num[0], str, cur[0], next, sum, dis);
154         Output(str, sum[0], dis, num[0]);
155     }
156 
157     private static void calThree(int num, int str[], int cur, int next[], int sum[], int dis[]) {
158         for (int i = 0, len = str.length; i < len; i++) {
159             if (str[i] == 0)
160                 str[i] = 0x3f3f3f3f;
161         }
162         Arrays.sort(str);
163         int[] vis = new int[num];
164         int curx = 0;
165         int cnt = 0;
166         for (int i = 0; i < num; i++) {
167             if (str[i] >= cur) {
168                 curx = i;
169                 break;
170             }
171 
172         }
173         for (int i = curx; i < num; i++) {
174             next[cnt++] = str[i];
175             dis[cnt - 1] = abs(cur - next[cnt - 1]);
176             sum[0] += abs(cur - next[cnt - 1]);
177             cur = str[i];
178 
179         }
180         for (int i = curx - 1; i >= 0; i--) {
181             next[cnt++] = str[i];
182             dis[cnt - 1] = abs(cur - next[cnt - 1]);
183             sum[0] += abs(cur - next[cnt - 1]);
184             cur = str[i];
185 
186         }
187     }
188 
189     private static void SSTF() {
190         int[] num = new int[1];
191         int[] cur = new int[1];
192         int[] str = new int[1000];
193         int[] dis = new int[1000];
194         int[] next = new int[1000];
195         Input(num, str, cur);
196         int[] sum = new int[1];
197         calTwo(num[0], str, cur[0], next, sum, dis);
198         Output(next, sum[0], dis, num[0]);
199     }
200 
201     private static void calTwo(int num, int[] str, int cur, int next[], int[] sum, int[] dis) {
202         int[] vis = new int[num];
203         int curx = cur;
204         int cnt = 0;
205         while (true) {
206             int len = 0x3f3f3f3f;
207             int pos = -1;
208             for (int i = 0; i < num; i++) {
209                 if (abs(str[i] - curx) < len && vis[i] == 0) {
210                     len = abs(str[i] - curx);
211                     pos = i;
212 
213                 }
214             }
215             if (pos == -1)
216                 return;
217             vis[pos] = 1;
218             dis[cnt] = abs(str[pos] - curx);
219             next[cnt++] = str[pos];
220             sum[0] += dis[cnt - 1];
221             curx = str[pos];
222         }
223     }
224 
225     private static int abs(int i) {
226         return i > -i ? i : -i;
227     }
228 
229     private static void FCFS() {
230         int[] num = new int[1];
231         int[] cur = new int[1];
232         int[] str = new int[100];
233         int[] dis = new int[1000];
234         Input(num, str, cur);
235 
236         int sum = calOne(str, dis, cur);
237         System.out.println(num);
238         Output(str, sum, dis, num[0]);
239 
240     }
241 
242 }
posted @ 2019-12-16 14:12  左手边五十米  阅读(415)  评论(0编辑  收藏  举报