Operating system disk arm shift scheduling algorithm simulation and implementation experiment code

1. Experimental algorithm

FCFS: Scheduling in order of access sequence

SSTF: Each time the cylinder number closest to the current head position is searched for scheduling

One-way scanning: Find the nearest one by one from the inside to the outside until the largest cylinder is scanned, then the smallest cylinder is scanned empty, and then the nearest one is searched one by one for scheduling

Two-way scanning: Find the nearest one by one according to the current head direction until the edge cylinder is scanned, and then scan back in the opposite direction

Elevator scheduling: Find the nearest one by one according to the current head direction, until all the ones that need to be accessed in this direction have been accessed, and then go back to find the nearest one by one for scheduling

2. Experiment code

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define N  1000
int length;
int sequence[N];    //访问柱面的顺序(从1开始)
int result[N];      //存放最短优先的结果
int now;            //当前柱面 
int count=0;        //记录移动柱面
int border = 199;   //最外层柱面
int resultLen = 0;  //输出结果的长度
//函数名:input 函数功能:输入访问序列信息
void input() {
    
    printf("请输入访问序列的长度:");
    scanf("%d", &length);
    printf("请输入访问的柱面顺序:");
    for (int i = 0; i < length; i++)
        scanf("%d", &sequence[i]);
    printf("请输入正在访问的柱面:");
    scanf("%d", &now);
    count = 0;      //初始化移动柱面
    resultLen = length+1;  //初始化输出长度
}

void printResult()
{
    printf("\n移动的顺序为:\n");
    for (int i = 0; i < resultLen; i++)
        printf("%d ", result[i]);
    printf("\n移动柱面为:%d", count);
    printf("\n");
}
//函数名:FCFS参数:无
void FCFS() {
    //函数功能:调用先来先服务算法
    for (int i = 0; i < length; i++)
    {
        result[i] = now;
        count += abs(now - sequence[i]);
        now = sequence[i];
    }
    result[length ] = now;

}

//函数名:SSTF 函数功能:调用短进程优先调度算法
void SSTF() {
    int min, nextPos;
    for (int i = 0; i < length; i++)
    {
        result[i] = now;
        min = 0x7fffffff;
        for (int j = 0; j < length; j++)    //寻找下一个位置
        {
            if (sequence[j] == -1)
                continue;
            if (abs(now - sequence[j]) < min)
            {
                min = abs(now - sequence[j]);
                nextPos = j;
            }
        }
        now = sequence[nextPos];
        count += min;
        sequence[nextPos] = -1;            //置为-1代表已经访问过
    }
    result[length] = now;
}

//将sequence数组升序排序
void sort() {//冒泡排序
    for (int i = 0; i < length-1; i++)      //进行len-1次即可
    {
        for (int j = 0; j < length-i-1; j++)  //下一次遍历减掉已经排好序的元素个数
        {
            if (sequence[j] > sequence[j+1])
            {
                int tmp = sequence[j];
                sequence[j] = sequence[j + 1];
                sequence[j + 1] = tmp;
            }
        }
    }
    printf("排序后的序列:");
    for (int i = 0; i < length; i++)
        printf("%d ", sequence[i]);
    printf("\n");
}
//函数名:Oneway_scan  函数功能:调用单向扫描算法
void Oneway_scan() {
    sort();
    int sum = 0,j;  //sum记录逆方向的元素个数
    while (sequence[sum] < now)//找到now所在位置,同时i也记录了小于now的个数
        sum++;
    if (sum == 0) //退化成类似FCFS
    {
        FCFS();
        return;
    }
    for (j = 0; j < length - sum; j++)//先处理处于移动方向正向的元素
    {
        result[j] = now;
        count += sequence[sum + j] - now; //已经排好序所以不需要取绝对值
        now = sequence[sum + j];
    }
    result[j++] = now;
    count += border - now;
    result[j++] = border;//处理好边界值
    count += border;     //处理移动柱面
    now = 0;
    for (int k = 0; k < sum; k++)       //处理剩余的元素
    {
        result[j++] = now;
        count += sequence[k] - now;
        now = sequence[k];
    }
    result[j] = now;
    resultLen = length + 3;
}

//函数名:Twoway_scan 函数功能:调用双向扫描算法
void Twoway_scan() {
    sort();
    int sum = 0,j;
    while (sequence[sum] < now)
        sum++;
    if (sum == 0)
    {
        FCFS();
        return;
    }
    for (j = 0; j < length - sum; j++)//正向扫一遍
    {
        result[j] = now;
        count += sequence[sum + j] - now; 
        now = sequence[sum + j];
    }
    result[j++] = now;
    result[j] = border; //调整边界值
    count += border - now;
    now = border;
    for (int k = sum - 1; k >= 0; k--)   //反向扫一遍
    {
        result[j++] = now;
        count += now - sequence[k];
        now = sequence[k];
    }
    result[j] = now;
    resultLen = length + 2;
}

//函数名:Elevator 函数功能:调用电梯调度算法
void Elevator() {
    sort();
    int sum = 0,j=0,saveNow=now;
    while (sequence[sum] < now)
        sum++;
    if (sum == 0)//单向,退化成FCFS(排序后)
    {
        FCFS();
        return;
    }
    printf("\n电梯调度(由里向外)");
    for (int k = sum - 1; k >= 0; k--)   //反向扫一遍
    {
        result[j++] = now;
        count += now - sequence[k];
        now = sequence[k];
    }
    result[j++] = now;
    for (j=sum; j < length; j++)//正向扫一遍
    {
        result[j] = now;
        count += sequence[ j] - now;
        now = sequence[j];
    }
    result[j] = now;
    printResult();
    now = saveNow;//重新初始化
    count = 0;
    printf("\n电梯调度(由外向里)");
    for (j = 0; j < length-sum; j++)//正向扫一遍,类似FCFS
    {
        result[j] = now;
        count += sequence[sum + j] - now; 
        now = sequence[sum + j];
    }
    for (int k = sum - 1; k >= 0; k--)   //反向扫一遍
    {
        result[j++] = now;
        count += now - sequence[k];
        now = sequence[k];
    }
    result[j] = now;
    printResult();
    
}

//选择菜单
void choice() {
    while (1) {
        printf("*************磁盘驱动调度**************\n");
        printf("       *     1.FCFS           *\n");
        printf("       *     2.SSTF           *\n");
        printf("       *     3.单向扫描       *\n");
        printf("       *     4.双向扫描       *\n");
        printf("       *     5.电梯调度       *\n");
        printf("       *     0.退出           *\n");
        printf("             请输入选项[ ]\b\b");
        int op;
        scanf("%d", &op);
        switch (op) {//选择算法
        case 1:
            input();
            printf("\n*********FCFS磁盘移臂调度过程*********\n");
            FCFS();
            printResult();
            break;
        case 2:
            input();
            printf("\n*********SSTF磁盘移臂调度过程*********\n");
            SSTF();
            printResult();
            break;
        case 3:
            input();
            printf("\n*********单向扫描过程*********\n");
            Oneway_scan();
            printResult();
            break;
        case 4:
            input();
            printf("\n*********双向扫描过程*********\n");
            Twoway_scan();
            printResult();
            break;
        case 5:
            input();
            printf("\n*********电梯调度过程*********\n");
            Elevator();
            break;
        default:printf("\n调度结束!");
            return;
        }
    }
}
//测试用例
//8 
//98 183 37 122 14 124 65 67
//53
int main()
{
    choice();
    return 0;
}

3. Experimental results

Guess you like

Origin blog.csdn.net/OrientalGlass/article/details/130935314