1. 程式人生 > >scan演算法進行磁碟排程

scan演算法進行磁碟排程

要求:

兩種實現方式:

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;
} 

第二個程式的輸出就寫簡單點了,主要是懶。。。。

本質上兩個程式是一樣的。