要求:
两种实现方式:
1,使用数组保存请求队列:
#include<cstdio> #include<stdlib.h> #include<time.h> using namespace std; const int N = 500; //设置得大点,防止溢出 const int MIN = 10000; //设置得大于最大磁道号即可 struct process{ //请求进程的结构 int name; int track; }; process p_queue[N]; // 请求队列 void ask(int n) { //请求 process temp; temp.name = rand() % 50000; //随机生成进程名 但是有出现同名请求的风险 temp.track = rand() / 200; //随机生成请求磁道 printf("创建请求:id: %d track: %d\n\n", temp.name, temp.track); p_queue[n] = temp; //将随机生成的请求加入请求队列 } void print_IO(int track, int dire, process p, int n) { //打印请求IO表, 当前磁道号,移臂方向,被选中的进程名和其要求的磁道 printf("处理请求===当前请求IO表:\n"); printf("进程名\t请求磁道\n"); for(int i = 0; i < n; i++) { if(p_queue[i].name!= -1) printf("%d\t%d\n", p_queue[i].name, p_queue[i].track); } printf("当前磁道号: %d\t臂方向: %d\n", track, dire); printf("被选中的进程名: %d\t要求的磁道号: %d\n\n", p.name, p.track); } void scheduling(int *dire, int *track, int n) { //处理 int trackName = 0, min = MIN; while(min == MIN) { //scan算法 if(*dire == 0) { for(int i = 0; i < n; i++) if(p_queue[i].name != -1 && p_queue[i].track > *track && p_queue[i].track - *track < min) { trackName = p_queue[i].name; min = p_queue[i].track - *track; } } else { for(int i = 0; i < n; i++) if(p_queue[i].name != -1 && p_queue[i].track < *track && *track - p_queue[i].track < min) { trackName = p_queue[i].name; min = *track - p_queue[i].track; } } if(min == MIN) *dire = ((*dire) == 0 ? 1 : 0); //如果到达了一端顶点, 磁臂反向 } for(int k = 0; k < n; k++) { if(p_queue[k].name == trackName) { print_IO(*track, *dire, p_queue[k], n); //打印请求信息 *track = p_queue[k].track; //更新track(当前磁道) p_queue[k].name = -1; //将进程名设为-1即代表注销进程,但是实际上注销进程仍然在请求队列中,只是通过判断条件使其对程序不可见 break; } } } // dire表示磁头运动方向 0:由 0 -> 199 1: 由 199 -> 0 // track表示磁头当前所在磁道 int main() { int dire, track, n = 0, remain = 0; //当前方向,磁道, 总请求数目, 未处理的请求 srand((unsigned int)time(NULL)); //随机生成初始方向和磁道 dire = rand() % 2; track = rand() % 200; printf("初始化: dire: %d track: %d\n", dire, track); //初始化5个请求 for(int i = 0; i < 5; i++) { ask(n++); remain++; } while(remain > 0) { int k = rand() % 3; //通过调节K值,调节产生两种进程的几率 if(k == 1 || k == 2) { //处理一个请求 scheduling(&dire, &track, n); remain--; } else { //产生一个请求 ask(n++); remain++; } } printf("请求队列已完成\n"); return 0; }
2:使用可变长数组保存请求队列:
#include<iostream> #include<cstdio> #include<stdlib.h> #include<time.h> #include<vector> using namespace std; const int N = 1000; struct request{ int id; int reqTrack; }; vector<request> req; void init(int *dire, int *track) { *dire = rand() % 2; *track = rand() % 200; } void schedAsk(){ //随机生成一个调度请求 request temp; temp.id = rand() % 10000; temp.reqTrack = rand() / 200; printf("创建请求:id: %d track: %d\n", temp.id, temp.reqTrack); req.push_back(temp); } /* // 不考虑id重复的情况 // 考虑方向问题(未解决) */ void diskSchedu(int *dire, int *track) { int need, n = req.size(), min = N; while(min == N) { //scan算法 if(*dire == 0) { for(int i = 0; i < n; i++) if(req[i].reqTrack > *track && req[i].reqTrack - *track < min) { need = req[i].id; min = req[i].reqTrack - *track; } } else { for(int i = 0; i < n; i++) if(req[i].reqTrack < *track && *track - req[i].reqTrack < min) { need = req[i].id; min = *track - req[i].reqTrack; } } if(min == N) *dire = ((*dire) == 0 ? 1 : 0); //如果到达了一端顶点, 磁臂反向 } vector<request>::iterator it; for(it = req.begin(); it != req.end();) { if((*it).id == need) { *track = (*it).reqTrack; //更新track printf("磁盘调度:id: %d track: %d dire: %d\n", (*it).id, (*it).reqTrack, *dire); it = req.erase(it); break; } else it++; } } /* // dire表示磁头运动方向 0:由 0 -> 199 1: 由 199 -> 0 // track表示磁头当前所在磁道 // k = 1 执行磁盘调度 k= 2 执行接收请求 */ int main() { srand((unsigned int)time(NULL)); int dire, track, n = 2; init(&dire, &track); printf("初始化: dire: %d track: %d\n", dire, track); for(int i = 0; i < n; i++) { //预先放置5个请求 schedAsk(); } printf("===========初始化结束========\n"); while(req.size() != 0) { int k = rand() % 3; //通过调节K值,调节产生两种进程的几率 if(k == 1 || k == 2) diskSchedu(&dire, &track); else { schedAsk(); } } if(req.size() == 0) cout << "已处理所有请求\n"; return 0; }
第二个程序的输出就写简单点了,主要是懒。。。。
本质上两个程序是一样的。