设计一个以电梯调度思想为主并考虑旋转优化的程序,对磁盘进行移臂和旋转调度,对磁盘进行移臂和旋转调度。 假定某个磁盘组共有 200 个柱面,由外向里顺序编号(0—199),每个柱面上有 20 个磁道,编号为 0—19,每个磁道分成 8 个物理记录,编号 0—7。进程访问磁盘的物理 地址可以用键盘输入的方法模拟得到。 图 4-1 中的初始化工作包括,初始化“请求 I/O”表,置当前移臂方向为里移; 置当前位置为 0 号柱面,0 号物理记录。程序运行前可假定“请求 I/O”表中已经有如干个进程等待访问磁盘。 在模拟实验中,当选中一个进程可以访问磁盘时,并不实际地启动磁盘,而用显示:“请求 I/O表;当前移臂方向;当前柱面号,物理记录号来代替图 4-3 中的“启动磁盘” 这项工作
/*模拟电梯调度算法,实现对磁盘的驱动调度。*/#include<iostream>#include<string>#include<iomanip>#include<cmath>using namespace std;typedef struct request {//请求I/O表string name;//进程名int cylinder;//柱面号int magnetic;//磁道号int record;//物理记录号}Request;int tableNum = 0;Request Table[100];Request current;void InitCurrent() {//初始化初始进程current.name = "初始进程";current.cylinder = 0;current.magnetic = 0;current.record = 0;//假定表中已经存在的请求Table[0].name = "请求A";Table[0].cylinder = 1;Table[0].magnetic = 5;Table[0].record = 0;Table[1].name = "请求B";Table[1].cylinder = 10;Table[1].magnetic = 4;Table[1].record = 2;Table[2].name = "请求C";Table[2].cylinder = 66;Table[2].magnetic = 3;Table[2].record = 6;Table[3].name = "请求D";Table[3].cylinder = 30;Table[3].magnetic = 4;Table[3].record = 5; Table[4].name = "请求E";Table[4].cylinder = 3;Table[4].magnetic = 1;Table[4].record = 3;Table[5].name = "请求F";Table[5].cylinder = 77;Table[5].magnetic = 0;Table[5].record = 1;}void CountTable() {int i;for (i = 0; Table[i].cylinder != NULL; i++) {}tableNum = i;}int FindNearest() {int min = 8, k;//最小距离,最小距离的编号int distance = 8;//当前距离for (int i = 0; i < tableNum; i++) {if (Table[i].cylinder == current.cylinder) {distance = abs(Table[i].record - current.record);if (distance < min) {min = distance;k = i;}}}return k;}void print_io() {//打印请求I/O表cout << "--------------------------请求I/O表---------------------------" << endl;cout << "进程名: 柱面号: 磁道号: 物理记录号:" << endl;for (int i = 0; i < tableNum; i++) {cout << setfill(' ') << setw(6) << Table[i].name << setfill(' ') << setw(15) << Table[i].cylinder << setfill(' ') << setw(16) << Table[i].magnetic << setfill(' ') << setw(17) << Table[i].record << endl;}cout << "--------------------------------------------------------------" << endl;}void PrintProcess(bool direction) {string directionStr;if (direction == 1) {directionStr = "up";}else {directionStr = "down";}cout << "------------------------选中的进程信息------------------------" << endl;cout << "进程名: 柱面号: 物理记录号: 方向:" << endl;cout << setfill(' ') << setw(6) << current.name << setfill(' ') << setw(15) <<current.cylinder << setfill(' ') << setw(16) << current.record << setfill(' ') << setw(17) << directionStr << endl;cout << "--------------------------------------------------------------" << endl;}int CylinderJudge() {//遍历请求表判断是否有与当前柱面号相同的访问者for (int i = 0; i < tableNum; i++) {if (Table[i].cylinder == current.cylinder){return i;}}return -1;}int CylinderMax() {int differenceC=200;//柱面号之差int t = 8;//最小物理记录int k;//选择出的最小柱面号int a;//选择出的最佳请求号for (int i = 0; i < tableNum; i++) {if (abs(Table[i].cylinder - current.cylinder) < differenceC && Table[i].cylinder > current.cylinder) {differenceC = Table[i].cylinder - current.cylinder;}k = current.cylinder + differenceC;}for (int i = 0; i < tableNum; i++) {if (Table[i].cylinder == k && Table[i].record < t) {t = Table[i].record;a = i;}}if (differenceC == 200) {//没有比当前柱面号大的访问请求return -1;}else {return a;}}int CylinderMin() {int differenceC = 200;//柱面号之差int t = 8;//最小物理记录int k;//选择出的最大柱面号int a;//选择出的最佳请求号for (int i = 0; i < tableNum; i++) {if (abs(Table[i].cylinder - current.cylinder) < differenceC && Table[i].cylinder < current.cylinder) {differenceC = abs(Table[i].cylinder - current.cylinder);}k = current.cylinder - differenceC;}for (int i = 0; i < tableNum; i++) {if (Table[i].cylinder == k && Table[i].record < t) {t = Table[i].record;a = i;}}if (differenceC == 200) {//没有比当前柱面号小的访问请求return -1;}else {return a;}}void PopProcess(int process) {for (int i = process; i < tableNum; i++) {Table[i] = Table[i + 1];}tableNum--;}int Scan(){int process;//选择的进程号bool direction =1; //方向0=out,1=in,默认移臂方向为向里移print_io();if (tableNum == 0) {//无等待访问者cout << "无等待访问者!!!" << endl;return 0;}else//有等待访问者{if (CylinderJudge() != -1) {//有与当前柱面号相同的访问者process = FindNearest();}else//没有与当前柱面号相同的访问者{if (direction == 1) {//移臂方向为向里process = CylinderMax();if (process == -1) {//没有比当前柱面号大的访问请求process = CylinderMin();direction = 0;}}else {//移臂方向为向外process = CylinderMin();if (process == -1) {//没有比当前柱面号小的访问请求process = CylinderMax();direction = 1;}}}current = Table[process];PrintProcess(direction);PopProcess(process);}}void Accept() {int flag = 1;while (flag == 1) {cout << "输入:进程名、柱面号、磁道号、物理记录号" << endl;cin >> Table[tableNum].name >> Table[tableNum].cylinder >> Table[tableNum].magnetic >> Table[tableNum].record;tableNum++;cout << "登记成功!继续登记请求按1否则按0" << endl;cin >> flag;}}void Init() {float n;int command=1;InitCurrent();//初始化当前位置CountTable();//统计IO请求表中请求数目while (command == 1) {cout << "输入在[0,1]区间内的一个随机数!!!" << endl;cin >> n;if (n > 0.5) {Scan();}else {Accept();}cout << "继续请按1,退出请按0" << endl;cin >> command;}}int main(){Init();}
运行结果: