磁盘调度算法
磁盘调度在多道程序设计的计算机系统中,各个进程可能会不断提出不同的对磁盘进行读/写操作的请求。由于有时候这些进程的发送请求的速度比磁盘响应的还要快,因此我们有必要为每个磁盘设备建立一个等待队列,常用的磁盘调度算法有以下四种:
先来先服务算法(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 }
本文来自博客园,作者:左手边五十米,转载请注明原文链接:https://www.cnblogs.com/moomcake/p/12048847.html