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

第二个程序的输出就写简单点了,主要是懒。。。。

本质上两个程序是一样的。

 

转载于:https://www.cnblogs.com/bearcarl/p/9084730.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值