当前位置:   article > 正文

操作系统-磁盘调度算法(SCAN、CSCAN)

cscan

目录

一、前言

二、要求实现的功能

三、运行结果

 四、代码

总结


一、前言

该系统名称为:磁盘调度算法2,使用的是C++。

二、要求实现的功能

设计主界面以灵活选择某算法,且以下算法都要实现

1、扫描算法(SCAN)

2、循环扫描算法(CSCAN)

并求出每种算法的平均寻道长度

三、运行结果

手动输入测试样例:    初始时磁头位置:45

                                    磁道序列:55 58 39 18 90 160 150 38 184

主界面:

 选择SCAN算法并手动输入磁道

 选择磁道算法并让系统自动输入磁道

 选择CSCAN算法并手动输入磁道

 选择CSCAN算法并让系统自动输入磁道

四、代码

代码如下:

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include<iostream>
  3. #include<cstdio>
  4. #include<cstdlib>
  5. #include<algorithm>
  6. #include <random>
  7. using namespace std;
  8. struct node
  9. {
  10. int positon;//磁道位置
  11. int moved;//磁道与当前磁头的距离
  12. int visit;//磁道是否被访问过
  13. }que[1010];//初始磁道序列
  14. void surface();
  15. void input();//输入函数
  16. void output2();//输出函数
  17. int dis(int a, int b);//两个磁道距离的绝对值
  18. void SCAN();//扫描法
  19. void CSCAN();//循环扫描法
  20. int sig, start, direction;//算法选择标志,当前磁头位置,磁头移动方向
  21. int num;//磁道数量
  22. int order[1010];//磁头访问的磁道序列
  23. int total;//磁头访问的总磁道数
  24. const int isVis = 1;//该磁道被访问过
  25. const int noVis = 0;//该磁道没被访问过
  26. const int bigger = 1;//向磁头号增大方向移动
  27. const int smaller = 0;//向磁头号减小方向移动
  28. int num3[8]={33,59,13,77,123,170,160,185};
  29. int a1;//选择自动输入还是手动输入
  30. int main()
  31. {
  32. string a="yes";
  33. while(a=="yes")
  34. {
  35. surface();
  36. //程序输入
  37. input();
  38. //选择算法
  39. switch (sig)
  40. {
  41. case 1:SCAN(); break;
  42. case 2:CSCAN(); break;
  43. }
  44. //程序输出
  45. output2();
  46. cout<<"\n是否重新选择算法(yes/no):";
  47. cin>>a;
  48. }
  49. return 0;
  50. }
  51. void surface()
  52. {
  53. printf("-------------------磁盘调度算法2-------------------\n");
  54. printf("---------------------------------------------------\n");
  55. printf("**********************功能菜单*********************\n\n");
  56. printf(" 1.扫描算法(SCAN) \n\n");//每次将磁头按照电梯的方式朝一个方向移动,到顶点后按相反方向折回
  57. printf(" 2.循环扫描算法(CSCAN) \n\n");
  58. printf(" 3.退出系统 \n\n");
  59. printf("***************************************************\n");
  60. printf("---------------------------------------------------\n\n\n");
  61. printf("请输入您想要使用的功能:");
  62. }
  63. void input()
  64. {
  65. //freopen("osin.txt", "r", stdin);
  66. //freopen("osout.txt", "w", stdout);
  67. cin >> sig; //算法选择标志
  68. start = 0;
  69. total = 0;
  70. cout<<"请输入当前磁头位置:";
  71. cin >> start;//初始磁头位置
  72. cout<<"请输入磁头移动方向(磁头号增大方向为1,否则为2):";
  73. cin >> direction;//磁头移动方向
  74. num = 0;
  75. char c;
  76. cout<<"------------------\n";
  77. cout<<"选择输入磁道方式\n";
  78. cout<<"1.手动输入\n";
  79. cout<<"2.自动输入\n";
  80. cout<<"------------------\n";
  81. cout<<"请输入选择的方式:";
  82. cin>>a1;
  83. if(a1==1)
  84. {
  85. cout<<"\n请输入磁道序列:";
  86. while (scanf("%d", &que[num].positon))//输入磁道序列
  87. {
  88. que[num].moved = 0;
  89. que[num].visit = noVis;
  90. num++;
  91. c = getchar();
  92. if (c == '\n')//遇到换行符则输入结束
  93. {
  94. break;
  95. }
  96. else if (c == ',')//遇到逗号则继续读取
  97. {
  98. continue;
  99. }
  100. }
  101. }
  102. else
  103. {
  104. cout<<"\n自动生成的磁道序列为:";
  105. while(num<=7)
  106. {
  107. // cout<<num3[num]+" ";
  108. que[num].positon=num3[num];
  109. que[num].visit = noVis;
  110. num++;
  111. }
  112. /* for(int i=0;i<=7;i++)
  113. {
  114. cout<<num3[i]+" ";
  115. }*/
  116. }
  117. }
  118. void output2()
  119. {
  120. double sum;
  121. if(a1==2)
  122. {
  123. for(int i=0;i<=7;i++)
  124. {
  125. printf("%d ",num3[i]);
  126. }
  127. }
  128. if(sig==1)
  129. {
  130. cout<<"\n-----------SCAN-----------\n";
  131. printf(" (从%d磁道开始)\n",order[0]);
  132. cout<<" 下一磁道号 移动距离\n" ;
  133. for (int i = 1; i <= num; i++)//磁头移动经过的磁道序列
  134. {
  135. if (i != num)
  136. {
  137. printf(" %-10d %-10d\n", order[i],abs(order[i]-order[i-1]));
  138. }
  139. else
  140. {
  141. printf(" %-10d %-10d\n", order[i],abs(order[i]-order[i-1]));
  142. }
  143. sum=i;
  144. }
  145. printf("平均寻道长度:%.1lf\n", total/(sum));//磁头移动经过的总磁道数
  146. cout<<"-----------SCAN结束------------";
  147. }
  148. if(sig==2)
  149. {
  150. cout<<"\n-----------CSCAN----------\n";
  151. printf(" (从%d磁道开始)\n",order[0]);
  152. for (int i = 1; i <= num; i++)//磁头移动经过的磁道序列
  153. {
  154. if (i != num)
  155. {
  156. printf(" %-10d %-10d\n", order[i],abs(order[i]-order[i-1]));
  157. }
  158. else
  159. {
  160. printf(" %-10d %-10d\n", order[i],abs(order[i]-order[i-1]));
  161. }
  162. sum=i;
  163. }
  164. printf("平均寻道长度:%.1lf\n", total/(sum));//磁头移动经过的总磁道数
  165. cout<<"-----------CSCAN结束------------";
  166. }
  167. }
  168. int dis(int a, int b)
  169. {
  170. return abs(a - b);
  171. }
  172. void SCAN()
  173. {
  174. order[0] = start;
  175. //构造电梯
  176. int sorted[1010];
  177. for (int i = 0; i < num; i++)
  178. {
  179. sorted[i] = que[i].positon;
  180. }
  181. sort(sorted, sorted + num);
  182. //距当前磁头距离最短的磁道号
  183. int mini = 0;
  184. while (start >= sorted[mini])//统计出大于初始磁道号的刺刀个数
  185. {
  186. mini++;
  187. }
  188. //开始运行电梯
  189. int ans = 1;
  190. if (direction == bigger)//向磁头号增大方向移动
  191. {
  192. //电梯上升
  193. for (int i = mini; i < num; i++)
  194. {
  195. order[ans] = sorted[i];//order是将要访问的磁道序列
  196. ans++;
  197. }
  198. total += (sorted[num - 1] - start);
  199. //电梯下降
  200. for (int i = mini - 1; i >= 0; i--)
  201. {
  202. order[ans] = sorted[i];
  203. ans++;
  204. }
  205. total += (sorted[num - 1] - sorted[0]);
  206. }
  207. else//向磁头号减小方向移动
  208. {
  209. //电梯下降
  210. for (int i = mini - 1; i >= 0; i--)
  211. {
  212. order[ans] = sorted[i];
  213. ans++;
  214. }
  215. total += (start - sorted[0]);
  216. //电梯上升
  217. for (int i = mini; i < num; i++)
  218. {
  219. order[ans] = sorted[i];
  220. ans++;
  221. }
  222. total += (sorted[num - 1] - sorted[0]);
  223. }
  224. }
  225. void CSCAN()
  226. {
  227. order[0] = start;
  228. //构造电梯
  229. int sorted[1010];
  230. for (int i = 0; i < num; i++)
  231. {
  232. sorted[i] = que[i].positon;
  233. }
  234. sort(sorted, sorted + num);
  235. //距当前磁头距离最短的磁道号
  236. int mini = 0;
  237. while (start > sorted[mini])
  238. {
  239. mini++;
  240. }
  241. //开始运行电梯
  242. int ans = 1;
  243. if (direction == bigger)//向磁头号增大方向移动
  244. {
  245. //电梯上升
  246. for (int i = mini; i < num; i++)
  247. {
  248. order[ans] = sorted[i];
  249. ans++;
  250. }
  251. //电梯循环
  252. for (int i = 0; i < mini; i++)
  253. {
  254. order[ans] = sorted[i];
  255. ans++;
  256. }
  257. //推导可得,total等于两端长度的两倍减去中间没有覆盖到的一段
  258. total += (2 * (sorted[num - 1] - sorted[0]) - (start - sorted[mini - 1]));
  259. }
  260. else//向磁头号减小方向移动
  261. {
  262. //电梯下降
  263. for (int i = mini - 1; i >= 0; i--)
  264. {
  265. order[ans] = sorted[i];
  266. ans++;
  267. }
  268. //电梯循环
  269. for (int i = num - 1; i >= mini; i--)
  270. {
  271. order[ans] = sorted[i];
  272. ans++;
  273. }
  274. //推导可得,total等于两端长度的两倍减去中间没有覆盖到的一段
  275. total += (2 * (sorted[num - 1] - sorted[0]) - (sorted[mini] - start));
  276. }
  277. }

总结

本次课设题目是磁盘调度算法,使我更加理解了磁盘调度算法的全过程。要实现该算法首先要了解算法的过程,最短寻道算法(SSTF)就是总会从等待访问者中挑选寻找时间最短的那个请求先执行的,无论是在磁盘的里面还是外面,只要离他近的就先执行。而循环扫描算法就和我们平时坐的电梯有点类似,先往一个方向运行。这次的实验里对总道数的计算一开始理解的不够全,尤其是循环扫描算法,但用电梯实例来想象模拟后我很快弄明白了怎么回事。

但是程序仍然有很多改进的地方,资源可以更加节约,算法也还有优化的余地,但是时间和精力有限,我会在课余的时间加深对磁盘调度的理解同时加上其他的算法,例如扫描调度(SCAN)算法,先来先服务(FCFS)等。这次实验也让我感觉到了算法才是程序的灵魂,没有好的算法就像巧妇难为无米之炊,即使有再好的工具和基本功,没有算法和基本思想也是不可行的。

通过实现磁盘调度算法的动态实现过程,让我更加清楚了算法的流程,非常深刻地了解了这几种调度算法的异同以及优缺点。不仅仅是上述四种调度算法,由于时间原因,没能实现C-LOOK调度算法。等有时间,我会亲自实现一遍C-LOOK算法,更加深入的了解磁盘调度算法的实际应用。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/394922
推荐阅读
相关标签
  

闽ICP备14008679号