操作系统(磁盘调度算法算法)

本文介绍了如何使用Python模拟FCFS、SSTF、SCAN和CSCAN四种磁盘调度算法,通过给定磁道访问序列和起始磁道,计算不同算法的平均寻道长度。结果显示,SSTF和SCAN在寻道效率上优于FCFS,而CSCAN具有一定的延迟优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

虚拟内存页面置换算法

一、实验环境

编译软件:pycharm

程序语言:python

二、问题描述:


        设计程序模拟先来先服务FCFS、最短寻道时间优先SSTF、SCAN和循环SCAN算法的工作过程。假设有n个磁道号所组成的磁道访问序列,给定开始磁道号m和磁头移动的方向(正向或者反向),分别利用不同的磁盘调度算法访问磁道序列,给出每一次访问的磁头移动距离,计算每种算法的平均寻道长度。

三、程序要求:

1)利用先来先服务FCFS、最短寻道时间优先SSTF、SCAN和循环SCAN算法模拟磁道访问过程。

2)模拟四种算法的磁道访问过程,给出每个磁道访问的磁头移动距离。

3)输入:磁道个数n和磁道访问序列,开始磁道号m和磁头移动方向(对SCAN和循环SCAN算法有效),算法选择1-FCFS,2-SSTF,3-SCAN,4-循环SCAN。

4)输出:每种算法的平均寻道长度。

四、实现提示:

用C++语言实现提示:

1)程序中进程调度时间变量描述如下:

const int MaxNumber=100;

int  TrackOrder[MaxNumber];

int  MoveDistance[MaxNumber];

double  AverageDistance;

bool direction;

2)进程调度的实现过程如下:

  • 变量初始化;
  • 接收用户输入磁道个数n和磁盘访问序列,选择算法1-FCFS,2-SSTF,3-SCAN,4-循环SCAN,输入开始磁盘号m和磁头移动方向;
  • 根据用户选择的算法进行磁道访问,输出磁盘调度算法的模拟过程;
  • 计算选择每次移动的磁头移动距离和算法的平均寻道长度;
  •  输出选择算法的平均寻道长度。

五、程序设计与结果分析

(一)程序设计

(1)先来先服务FCFS

设计思想:根据进程请求访问磁盘的先后次序进行调度。

源代码:

def FCFS(access_sequence, start):
    total_head_movement = 0  # 总移动距离
    movements = []  # 存储每次移动的距离
    for request in access_sequence:
        movement = abs(request - start)  # 计算当前请求磁道号与起始磁道号的距离
        total_head_movement += movement  # 累加总移动距离
        movements.append(movement)  # 将当前移动距离加入列表
        start = request  # 更新起始磁道号为当前请求磁道号
        print(f"移动到磁道 {request}")  # 输出当前移动到的磁道号
print(f"移动距离{movements}")  # 输出每次移动的距离列表
print(f"磁道访问序列: {access_sequence}")#输出磁道访问序列
    avg_seek_length = total_head_movement / len(access_sequence)  # 计算平均寻道长度
    return avg_seek_length  # 返回平均寻道长度

(2)最短寻道时间优先SSTF

设计思想:要求访问的磁道与当前磁头所在的磁道距离最近,以使每次的寻道时间最短。

源代码:

def SSTF(access_sequence, start):
    total_head_movement = 0  # 初始化总移动距离
    visited_sequence = []  # 存储访问顺序的列表
    movements = []  # 存储每次移动距离的列表
    # 当访问序列不为空时进行循环
    while access_sequence:
        # 找到最接近当前位置的磁道
        closest = min(access_sequence, key=lambda x: abs(x - start))
        movement = abs(closest - start)  # 计算移动距离
        total_head_movement += movement  # 更新总移动距离
        movements.append(movement)  # 记录移动距离
        start = closest  # 更新当前位置为最近磁道位置
        access_sequence.remove(closest)  # 从访问序列中移除当前访问的磁道
        visited_sequence.append(closest)  # 记录访问顺序
        print(f"移动到磁道 {closest},移动距离 {movement}")  # 打印当前移动信息
    # 打印最终的磁道访问序列和移动距离
    print(f"磁道访问序列: {visited_sequence}")
    print(f"移动距离(磁道数): {movements}")
    # 计算平均寻道长度(如果访问序列不为空)
avg_seek_length = total_head_movement / len(visited_sequence) 
return avg_seek_length # 返回平均寻道长度

(3)扫描(SCAN)算法

 

设计思想:

        赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间t。当需淘汰一个页面时,选择现有页面中其t值最大的,即最久未使用的页面予以淘汰。基于优先级的调度算法,当有新进程的请求到达,且其所要访问的磁道与磁头当前所在磁道的距离较近,则该新的进程请求优先满足;扫描算法不仅考虑到欲访问的磁道与当前磁道间的距离,更优先考虑磁头当前的移动方向。

源代码:

def SCAN(access_sequence, start, direction):
    total_head_movement = 0  # 初始化总移动距离
    visited_sequence = []  # 存储访问序列
    movements = []  # 存储移动距离
    # 根据方向对访问序列进行排序(正向或反向)
    if direction == "forward":
        access_sequence.sort()
    else:
        access_sequence.sort(reverse=True)
    # 当访问序列不为空时进行循环
    while access_sequence:
        # 根据方向找到最近的磁道
        if direction == "forward":
            closest = min(filter(lambda x: x >= start, access_sequence), default=None)
            if closest is None:
                direction = "backward"
                continue
        else:
            closest = max(filter(lambda x: x <= start, access_sequence), default=None)
            if closest is None:
                direction = "forward"
                continue
        # 计算移动距离并更新总移动距离
        movement = abs(closest - start)
        total_head_movement += movement
        movements.append(movement)  # 记录移动距离
        start = closest  # 更新当前位置为找到的磁道
        access_sequence.remove(closest)  # 移除已访问的磁道
        visited_sequence.append(closest)  # 记录访问的磁道
        print(f"移动到磁道 {closest},移动距离 {movement}")
    # 打印访问序列和移动距离
    print(f"磁道访问序列: {visited_sequence}")
    print(f"移动距离(磁道数): {movements}")
    # 计算平均寻道长度(如果访问序列不为空)
    avg_seek_length = total_head_movement / len(visited_sequence)
    return avg_seek_length

(4)循环扫描(CSCAN)算法

 

设计思想:CSCAN算法规定磁头单向移动,最小磁道号紧接着最大磁道号构成循环,进行循环扫描。

源代码:

def C_SCAN(access_sequence, start, direction):
    total_head_movement = 0  # 初始化总移动距离
    visited_sequence = []  # 存储访问序列
    movements = []  # 存储移动距离
    access_sequence.sort()  # 对访问序列进行排序

    # 当访问序列不为空时进行循环
    while access_sequence:
        # 根据方向找到最近的磁道
        if direction == "forward":
            closest = min(filter(lambda x: x >= start, access_sequence), default=None)
            if closest is None:
                closest = access_sequence[0]
        else:
            closest = max(filter(lambda x: x <= start, access_sequence), default=None)
            if closest is None:
                closest = access_sequence[-1]
        # 计算移动距离并更新总移动距离
        movement = abs(closest - start)
        total_head_movement += movement
        movements.append(movement)  # 记录移动距离
        start = closest  # 更新当前位置为找到的磁道
        access_sequence.remove(closest)  # 移除已访问的磁道
        visited_sequence.append(closest)  # 记录访问的磁道
        print(f"移动到磁道 {closest},移动距离 {movement}")  # 打印当前移动信息
    # 打印访问序列和移动距离
    print(f"磁道访问序列: {visited_sequence}")
    print(f"移动距离(磁道数): {movements}")
    # 计算平均寻道长度(如果访问序列不为空)
    avg_seek_length = total_head_movement / len(visited_sequence) if len(visited_sequence) > 0 else 0
    return avg_seek_length

 (4)主程序

# 主程序
n = int(input("输入磁道数目: "))
access_sequence = list(map(int, input("输入磁道访问序列: ").split()))
start = int(input("输入起始磁道: "))
direction = input("输入移动方向 (forward 或 backward): ")
algorithm_choice = int(input("选择算法 (1-FCFS, 2-SSTF, 3-SCAN, 4-C-SCAN): "))

if algorithm_choice == 1:
    avg_seek_length = FCFS(access_sequence, start)
elif algorithm_choice == 2:
    avg_seek_length = SSTF(access_sequence, start)
elif algorithm_choice == 3:
    avg_seek_length = SCAN(access_sequence, start, direction)
elif algorithm_choice == 4:
    avg_seek_length = C_SCAN(access_sequence, start, direction)
else:
    print("选择无效")
print(f"平均寻道长度: {avg_seek_length}")

(二)运行结果 

1.先来先服务FCFS算法运行结果:

2.最短寻道时间算法运行结果:

3.扫描(SCAN)算法运行结果:

4.循环扫描(CSCAN)算法运行结果:

(三)结果分析

根据实验数据绘制上面的结果对比图并结合各算法的设计原理,可以得出以下结论:

  1. 先来先服务(FCFS)算法对比其他算法平均寻道距离最大,FCFS中每个进程的请求都能依次地得到处理,不会出现某各进程的请求长期得不到满足的情况,所以适用于进程数目较少的场合。
  2. SSTF算法平均每次磁头移动的距离明显低于FCFS算法的距离,SSTF较FCFS有更好的寻道性能。SSTF与SCAN算法的平均寻道距离较为接近。
  3. SCAN算法能够提供较小的平均寻到长度,因为它按照一个方向依次服务请求,然后改变方向,避免了某些请求长时间等待。在平均情况下,磁头的平均移动距离相对较少。SCAN算法和CSCAN算法在每次访问磁道号的移动距离上具有较为相似的表现,但是SCAN算法具有更优的平均寻道长度。
  4. CSCAN的平均寻道距离在四个算法中处于中等的位置,从理论上分析,CSCAN在处理请求进程的请求延迟方面具有优势。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值