成都工业学院2021级操作系统专周课程设计FCFS,SSTF,SCAN,LOOK算法的实现

news2024/11/18 14:23:33

运行环境

操作系统:Windows 11 家庭版

运行软件:CLion 2023.2.2

源代码文件

#include <iostream>
#include <vector>
#include <algorithm>
#include <random>
using namespace std;

// 生成随机数
int generateRandomNumber(int min, int max) {
    random_device rd;
    mt19937 gen(rd());
    uniform_int_distribution<> dis(min, max);
    return dis(gen);
}

// 计算引臂移动量
int calculateArmMovement(const vector<int>& movementSequence) {
    int movement = 0;
    for (int i = 1; i < movementSequence.size(); ++i) {
        movement += abs(movementSequence[i] - movementSequence[i-1]);
    }
    return movement;
}

// 计算寻道时间
int calculateSeekTime(int armMovement, int timePerTrack) {
    return armMovement * timePerTrack;
}

// 计算平均旋转延迟时间
int calculateRotationDelay(int armMovement, int diskSpeed) {
    return (armMovement * 60000) / diskSpeed; // 因转速为转/分钟,转成毫秒需要乘以60000
}

// 计算传输时间
int calculateTransferTime(int numRequests, int sectorsPerTrack, int sectorSize, int diskSpeed) {
    int transferTime = (numRequests * sectorsPerTrack * sectorSize * 1000) / diskSpeed; // 字节数除以转速得到毫秒数
    return transferTime;
}

// 计算总处理时间
int calculateTotalProcessingTime(int seekTime, int rotationDelay, int transferTime) {
    return seekTime + rotationDelay + transferTime;
}

// 显示引臂移动序列
void displayArmMovementSequence(const vector<int>& movementSequence) {
    for (int i = 0; i < movementSequence.size(); ++i) {
        cout << movementSequence[i] << " ";
    }
    cout << endl;
}

// SSTF算法
void sstfAlgorithm(vector<int>& ioRequests, int currentTrack, int timePerTrack, int diskSpeed, int sectorsPerTrack, int sectorSize) {
    cout << "SSTF算法:" << endl;
    vector<int> armMovementSequence;
    armMovementSequence.push_back(currentTrack); // 先添加当前磁道到移动序列

    while (!ioRequests.empty()) {
        int minDistance = INT_MAX;
        int nextTrack = -1;

        for (int i = 0; i < ioRequests.size(); ++i) {
            int distance = abs(currentTrack - ioRequests[i]);
            if (distance < minDistance) {
                minDistance = distance;
                nextTrack = ioRequests[i];
            }
        }

        armMovementSequence.push_back(nextTrack);
        currentTrack = nextTrack;
        ioRequests.erase(find(ioRequests.begin(), ioRequests.end(), nextTrack));
    }

    displayArmMovementSequence(armMovementSequence);
    int armMovement = calculateArmMovement(armMovementSequence);
    int seekTime = calculateSeekTime(armMovement, timePerTrack);
    int rotationDelay = calculateRotationDelay(armMovement, diskSpeed);
    int numRequests = ioRequests.size();
    int transferTime = calculateTransferTime(numRequests, sectorsPerTrack, sectorSize, diskSpeed);
    int totalProcessingTime = calculateTotalProcessingTime(seekTime, rotationDelay, transferTime);

    cout << "引臂移动量: " << armMovement << endl;
    cout << "寻道时间: " << seekTime << " 毫秒" << endl;
    cout << "平均旋转延迟时间: " << rotationDelay << " 毫秒" << endl;
    cout << "传输时间: " << transferTime << " 毫秒" << endl;
    cout << "所有访问处理时间: " << totalProcessingTime << " 毫秒" << endl;
}

//SCAN算法
void scanAlgorithm(vector<int>& ioRequests, int currentTrack, int timePerTrack, int diskSpeed, int sectorsPerTrack, int sectorSize) {
    cout << "SCAN算法:" << endl;
    vector<int> scanArmMovementSequence;
    int maxTrack = *max_element(ioRequests.begin(), ioRequests.end());
    int minTrack = *min_element(ioRequests.begin(), ioRequests.end());
    scanArmMovementSequence.push_back(currentTrack);

    vector<int> tempStack;
    vector<bool> visitedTracks(200, false); // 初始化标记数组,200是磁道的数量

    if (currentTrack >= maxTrack) {
        // 先向内扫描
        tempStack.push_back(0); // 添加0进入栈
        visitedTracks[0] = true;

        for (int track = currentTrack - 1; track >= minTrack; --track) {
            if (find(ioRequests.begin(), ioRequests.end(), track) != ioRequests.end() && !visitedTracks[track]) {
                tempStack.push_back(track);
                visitedTracks[track] = true;
            }
        }

        sort(tempStack.begin(), tempStack.end()); // 对栈进行排序

        // 将栈中的磁道添加到移动序列
        for (int track : tempStack) {
            scanArmMovementSequence.push_back(track);
        }

        // 到达最小磁道号后折返,向外扫描
        for (int track = minTrack + 1; track <= maxTrack; ++track) {
            if (find(ioRequests.begin(), ioRequests.end(), track) != ioRequests.end() && !visitedTracks[track]) {
                scanArmMovementSequence.push_back(track);
                visitedTracks[track] = true;
            }
        }
    } else {
        // 先向外扫描
        tempStack.push_back(199); // 添加199进入栈
        visitedTracks[199] = true;

        for (int track = currentTrack + 1; track <= maxTrack; ++track) {
            if (find(ioRequests.begin(), ioRequests.end(), track) != ioRequests.end() && !visitedTracks[track]) {
                tempStack.push_back(track);
                visitedTracks[track] = true;
            }
        }

        sort(tempStack.begin(), tempStack.end()); // 对栈进行排序

        // 将栈中的磁道添加到移动序列
        for (int track : tempStack) {
            scanArmMovementSequence.push_back(track);
        }

        // 到达最大磁道号后折返,向内扫描
        for (int track = maxTrack - 1; track >= minTrack; --track) {
            if (find(ioRequests.begin(), ioRequests.end(), track) != ioRequests.end() && !visitedTracks[track]) {
                scanArmMovementSequence.push_back(track);
                visitedTracks[track] = true;
            }
        }
    }

    displayArmMovementSequence(scanArmMovementSequence);
    int scanArmMovement = calculateArmMovement(scanArmMovementSequence);
    int scanSeekTime = calculateSeekTime(scanArmMovement, timePerTrack);
    int scanRotationDelay = calculateRotationDelay(scanArmMovement, diskSpeed);
    int scanNumRequests = ioRequests.size();
    int scanTransferTime = calculateTransferTime(scanNumRequests, sectorsPerTrack, sectorSize, diskSpeed);
    int scanTotalProcessingTime = calculateTotalProcessingTime(scanSeekTime, scanRotationDelay, scanTransferTime);

    cout << "引臂移动量: " << scanArmMovement << endl;
    cout << "寻道时间: " << scanSeekTime << " 毫秒" << endl;
    cout << "平均旋转延迟时间: " << scanRotationDelay << " 毫秒" << endl;
    cout << "传输时间: " << scanTransferTime << " 毫秒" << endl;
    cout << "所有访问处理时间: " << scanTotalProcessingTime << " 毫秒" << endl;
    // 在最后释放visitedTracks的空间
    visitedTracks.clear();
    displayArmMovementSequence(scanArmMovementSequence);
}

// LOOK算法
void lookAlgorithm(vector<int>& ioRequests, int currentTrack, string direction, int timePerTrack, int diskSpeed, int sectorsPerTrack, int sectorSize) {
    cout << "LOOK算法:" << endl;
    vector<int> armMovementSequence;
    int maxTrack = *max_element(ioRequests.begin(), ioRequests.end());
    int minTrack = *min_element(ioRequests.begin(), ioRequests.end());
    armMovementSequence.push_back(currentTrack); // 先添加当前磁道到移动序列

    if (direction == "outward") {
        // 向外扫描
        for (int track =  currentTrack + 1; track <= maxTrack; ++track) {
            if (find(ioRequests.begin(), ioRequests.end(), track) != ioRequests.end()) {
                armMovementSequence.push_back(track);
            }
        }
        // 向内扫描
        for (int track = currentTrack - 1; track >= minTrack; --track) {
            if (find(ioRequests.begin(), ioRequests.end(), track) != ioRequests.end()) {
                armMovementSequence.push_back(track);
            }
        }
    } else {
        // 向内扫描
        for (int track = currentTrack - 1; track >= minTrack; --track) {
            if (find(ioRequests.begin(), ioRequests.end(), track) != ioRequests.end()) {
                armMovementSequence.push_back(track);
            }
        }
        // 向外扫描
        for (int track = currentTrack + 1; track <= maxTrack; ++track) {
            if (find(ioRequests.begin(), ioRequests.end(), track) != ioRequests.end()) {
                armMovementSequence.push_back(track);
            }
        }
    }

    displayArmMovementSequence(armMovementSequence);
    int armMovement = calculateArmMovement(armMovementSequence);
    int seekTime = calculateSeekTime(armMovement, timePerTrack);
    int rotationDelay = calculateRotationDelay(armMovement, diskSpeed);
    int numRequests = ioRequests.size();
    int transferTime = calculateTransferTime(numRequests, sectorsPerTrack, sectorSize, diskSpeed);
    int totalProcessingTime = calculateTotalProcessingTime(seekTime, rotationDelay, transferTime);

    cout << "引臂移动量: " << armMovement << endl;
    cout << "寻道时间: " << seekTime << " 毫秒" << endl;
    cout << "平均旋转延迟时间: " << rotationDelay << " 毫秒" << endl;
    cout << "传输时间: " << transferTime << " 毫秒" << endl;
    cout << "所有访问处理时间: " << totalProcessingTime << " 毫秒" << endl;
}

// 根据选择的调度算法进行处理
void processAlgorithm(vector<int>& ioRequests, int currentTrack, int timePerTrack, int startupTime, int diskSpeed, int sectorsPerTrack, int sectorSize, const string& algorithmName) {
    vector<int> armMovementSequence;
    if (algorithmName == "FCFS") {
        armMovementSequence = ioRequests;  // 直接按照顺序处理请求
    } else if (algorithmName == "SSTF") {
        sstfAlgorithm(ioRequests, currentTrack, timePerTrack, diskSpeed, sectorsPerTrack, sectorSize);
        return;
    } else if (algorithmName == "SCAN") {
        scanAlgorithm(ioRequests, currentTrack, timePerTrack, diskSpeed, sectorsPerTrack, sectorSize);
        return;
    } else if (algorithmName == "LOOK") {
        lookAlgorithm(ioRequests, currentTrack, "outward", timePerTrack, diskSpeed, sectorsPerTrack, sectorSize);
        return;
    } else {
        cout << "未知的调度算法:" << algorithmName << endl;
        return;
    }

    armMovementSequence.insert(armMovementSequence.begin(), currentTrack);  // 加入初始位置
    displayArmMovementSequence(armMovementSequence);

    int armMovement = calculateArmMovement(armMovementSequence);
    int seekTime = calculateSeekTime(armMovement, timePerTrack);
    int rotationDelay = calculateRotationDelay(armMovement, diskSpeed);
    int numRequests = ioRequests.size();
    int transferTime = calculateTransferTime(numRequests, sectorsPerTrack, sectorSize, diskSpeed);
    int totalProcessingTime = calculateTotalProcessingTime(seekTime, rotationDelay, transferTime);

    cout << "引臂移动量: " << armMovement << endl;
    cout << "寻道时间: " << seekTime << " 毫秒" << endl;
    cout << "平均旋转延迟时间: " << rotationDelay << " 毫秒" << endl;
    cout << "传输时间: " << transferTime << " 毫秒" << endl;
    cout << "所有访问处理时间: " << totalProcessingTime << " 毫秒" << endl;
}

int main() {
    int initialTrack; // 磁头初始位置
    cout << "请输入磁头初始位置:";
    cin >> initialTrack;
    int timePerTrack;  // 跨越1个磁道所用时间(毫秒)
    int startupTime;   // 启动时间(毫秒)
    int diskSpeed;     // 磁盘转速(转/分钟)
    int sectorsPerTrack;  // 每磁道扇区数
    int sectorSize;    // 每扇区字节数

    cout << "请输入跨越1个磁道所用时间(毫秒):";
    cin >> timePerTrack;
    cout << "请输入启动时间(毫秒):";
    cin >> startupTime;
    cout << "请输入磁盘转速(转/分钟):";
    cin >> diskSpeed;
    cout << "请输入每磁道扇区数:";
    cin >> sectorsPerTrack;
    cout << "请输入每扇区字节数:";
    cin >> sectorSize;

    vector<int> ioRequests;
    vector<int> diskTrackNumbers;
    for(int i=1; i<201; i++){
        diskTrackNumbers.push_back(i);
    } // 磁道号固定为0到10
    int currentTrack = initialTrack; // 修改为用户输入的初始位置
    string direction = (generateRandomNumber(0, 1) == 0) ? "outward" : "inward"; // 添加这一行以初始化方向

    // 生成随机磁道I/O请求序列
    cout << "生成的随机磁道I/O请求序列:" << endl;
    for (int i = 0; i < 6; ++i) {
        int track = generateRandomNumber(0, diskTrackNumbers.size() - 1);
        ioRequests.push_back(diskTrackNumbers[track]);
        cout << ioRequests[i] << " ";
    }
    cout << endl;

    // 选择调度算法
    string algorithmName;
    cout << "请选择调度算法(FCFS、SSTF、SCAN、LOOK):";
    cin >> algorithmName;

    // 处理IO请求
    processAlgorithm(ioRequests, currentTrack, timePerTrack, startupTime, diskSpeed, sectorsPerTrack, sectorSize, algorithmName);

    return 0;
}

 源代码示例

 运行结果截图

FCFS算法

SSTF算法

 SCAN算法

LOOK算法

 注意事项

1、算法可能有点问题,大多数情况下是没有问题的

2、由于不同编译器可能不兼容,所以本人把代码都写在一起,避免了分文件造成的错误

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1309078.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

12.13_黑马数据结构与算法笔记Java

目录 098 堆 heapify 3 099 堆 增删替换 100 堆 e01 堆排序 100 堆e02 求数组第k大元素 100 堆e03 求数据流第k大元素 100 堆e04 求数据流中位数1 100 堆e04 求数据流中位数2 100 堆e04 求数据流中位数3 101 二叉树 概述 102 二叉树 深度优先遍历 103 二叉树 前中后…

2024年顶级的9个 Android 数据恢复工具(免费和付费)

不同的事情可能会损坏您的Android手机并导致您丢失数据。但大多数时候&#xff0c;您可以使用取证工具恢复部分或全部文件。 问题可能来自手机的物理损坏、磁盘的逻辑故障、完整的系统擦除&#xff0c;或者只是简单的粗心大意。 但是&#xff0c;无论数据丢失的原因是什么&am…

路由基本原理

目录 一、路由器概述 二、路由器的工作原理 三、路由表的形成 四、路由配置 1.连接设备 2.进入系统模式 3.进入接口模式 4.配置网络 5.下一跳的设置 6.设置浮动路由 7.设置默认路由 一、路由器概述 路由器&#xff08;Router&#xff09;是一种用于连接不同网络或子…

MySQL和Redis有什么区别?

目录 一、什么是MySQL 二、什么是Redis 三、MySQL和Redis的区别 一、什么是MySQL MySQL是一种开源的关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;它是最流行的数据库之一。MySQL以其高性能、可靠性和易用性而闻名&#xff0c;广泛应用于各种Web应用程序…

单片机的低功耗模式介绍

文章目录 简介一、功耗来源说明1.1、芯片工作模式1.2、静态损耗1.3、I/O额外损耗1.4、动态损耗 二、功耗如何测量三、降低功耗有什么方法3.1、选取合适的芯片工作模式3.2、降低工作频率3.3、关闭不需要使用的外设3.4、 降低静态电流损耗3.5、 周期采集供电3.6、 设置IO口状态 四…

MYSQL各种日志

感谢B站up主的视频分享 黑马程序员 MySQL数据库入门到精通&#xff0c;从mysql安装到mysql高级、mysql优化全囊括_哔哩哔哩_bilibili

FMETP STREAM 2.0

FMETPSTREAM简化了Unity3D中的直播,无需编码。设置和测试仅需5分钟。 "编码器模块"将Unity游戏视图、网络摄像头、桌面、声音和麦克风输入转换为字节数据,使其完美适用于各种流媒体场景。 优化的网络模块支持Server-clients连接类型,并允许您使用单个命令向 Serve…

el-date-picker限制选择7天内禁止内框选择

需求&#xff1a;elementPlus时间段选择框需要满足&#xff1a;①最多选7天时间。②不能手动输入。 <el-date-picker v-model"timeArrange" focus"timeEditable" :editable"false" type"datetimerange" range-separator"至&qu…

六.聚合函数

聚合函数 1.什么是聚合函数1.1AVG和SUM函数1.2MIN和MAX函数1.3COUNT函数 2.GROUP BY2.1基本使用2.2使用多个列分组2.3GROUP BY中使用WITH ROLLUP 3.HAVING3.1基本使用3.2WHERE和HAVING的区别 4.SELECT的执行过程4.1查询的结构4.2SELECT执行顺序4.3SQL执行原理 1.什么是聚合函数…

微服务实战系列之MQ

前言 从今天起&#xff0c;席卷北国的雪&#xff0c;持续了一整天&#xff0c;北京也不例外。这场意外的寒潮&#xff0c;把整个冬天渲染的格外cool。当然你可以在外面打雪仗、堆雪人、拉雪橇&#xff0c;也可以静坐屋内&#xff0c;来一场围炉煮茶的party。此刻&#xff0c;冬…

在IDEA中配置Git的Push键

前言 笔者在重新安装IDEA过程中需要重新绑定了Git&#xff0c;发现提交代码过程中push键消失了&#xff0c;所以笔者就以这篇文章记录一下Git配置push键的详细过程。 注意笔者当前IDEA版本为2019&#xff0c;可能和读者有所区别&#xff0c;但是操作思路是差不多的。 操作步…

Ubuntu22.04切换用户

一、只有一个用户时没有切换用户菜单项 1、用户信息 cat /etc/passwd 2、系统菜单 二、添加用户 添加新用户ym&#xff0c;全名yang mi 三、有两个及以上的用户时出现切换用户菜单项 1、用户信息 cat /etc/passwd 2、系统菜单 四、切换用户 1、点击上图中Switch User …

Python数据科学视频讲解:Python的数据运算符

2.9 Python的数据运算符 视频为《Python数据科学应用从入门到精通》张甜 杨维忠 清华大学出版社一书的随书赠送视频讲解2.9节内容。本书已正式出版上市&#xff0c;当当、京东、淘宝等平台热销中&#xff0c;搜索书名即可。内容涵盖数据科学应用的全流程&#xff0c;包括数据科…

关于标准库中的list(涉及STL的精华-迭代器的底层)

目录 关于list list常见接口实现 STL的精华之迭代器 关于list list的文档介绍 1. list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。 2. list的底层是双向链表结构&#xff0c;双向链表中每个元素存储在互不相关的独立…

为什么要使用国际语音群呼系统?

1.降本增效 通过批量导入客户的电话号码&#xff0c;由系统自动完成批量呼叫&#xff0c;企业可以节省人工拨号的费用&#xff0c;高效助力企业业务增长&#xff1b; 2.降低流失 通过批量群呼&#xff0c;企业可以724小时高并发无故障运行&#xff0c;智能锁定意向客户&…

java代码编写twitter授权登录

在上一篇内容已经介绍了怎么申请twitter开放的API接口。 下面介绍怎么通过twitter提供的API&#xff0c;进行授权登录功能。 开发者页面设置 首先在开发者页面开启“用户认证设置”&#xff0c;点击edit进行信息编辑。 我的授权登录是个网页&#xff0c;并且只需要进行简单的…

UML概扩知识点

UML是一个重要的知识点&#xff0c;考察的频度也很高。我们需要了解的是UML的一系列的图&#xff0c;红框里的是最核心的。 其次是对各种关系有了解&#xff08;红框里的&#xff1a; 依赖关系&#xff0c;关联关系&#xff0c;泛化关系&#xff0c;实现关系&#xff09; UM…

01.前言

前言 1.什么是前端开发 前端开发是创建 Web 页面或 app 等前端界面呈现给用户的过程核心技术&#xff1a;HTML&#xff0c;CSS&#xff0c;JavaScript 以及衍生出的各种技术&#xff0c;框架等 2.前端开发应用场景 3.前端职业路线 4.什么是CS架构与BS架构 介绍 应用软件&a…

项目总体测试计划书-word原件

编写此测试方案的目的在于明确测试内容、测试环境、测试人员、测试工作进度计划等&#xff0c;以保证测试工作能够在有序的计划安排进行。

【如何理解select、poll、epoll?】

如何理解select、poll、epoll&#xff1f; select、poll、epollselectpollepoll 知识扩展三者之间的主要区别是什么&#xff1f;epoll的两种模式是什么&#xff1f; select、poll、epoll select、poll、epoll都是Linux中常见的I/O多路复用技术&#xff0c;他们可以用于同时监听…