📜  SCAN(电梯)磁盘调度算法

📅  最后修改于: 2021-04-21 22:29:09             🧑  作者: Mango

先决条件磁盘调度算法。
给定一个磁盘磁道编号和初始磁头位置的数组,如果使用了SCAN磁盘调度算法,我们的任务是查找为访问所有请求的磁道而执行的查找操作的总数。

SCAN(电梯)算法
在SCAN磁盘调度算法中,磁头从磁盘的一端开始,朝磁盘的另一端移动,一个接一个地处理请求,然后到达另一端。然后,磁头的方向相反,并且随着磁头不断地来回扫描以访问磁盘,该过程继续进行。因此,该算法可以用作电梯,因此也称为电梯算法。结果,中端的请求得到了更多的服务,那些到达磁盘臂后面的请求将不得不等待。

SCAN(电梯)算法的优点

  1. 该算法简单易懂。
  2. SCAN算法没有饥饿感。
  3. 该算法优于FCFS调度算法。

SCAN(电梯)算法的缺点

  1. 实施更复杂的算法。
  2. 该算法是不公平的,因为它会导致磁头刚访问的汽缸的等待时间较长。
  3. 这样会导致磁头移动到磁盘末端,这样到达手臂位置之前的请求将立即得到服务,但是到达手臂位置后面的其他一些请求将不得不等待该请求完成。

算法-

  1. 让Request数组代表一个数组,该数组存储已按其到达时间的升序请求的音轨的索引。 “磁头”是磁盘磁头的位置。
  2. 让方向代表头部向左还是向右移动。
  3. 在头部移动的方向上,所有人都一一追踪。
  4. 计算磁头到磁头的绝对距离。
  5. 以此距离增加总寻道数。
  6. 当前服务的轨道位置现在变为新的头位置。
  7. 转到步骤3,直到到达磁盘的一端。
  8. 如果到达磁盘末尾,请反转方向,然后继续执行步骤2,直到请求阵列中的所有磁道都未送达为止。

例子:

Input: 
Request sequence = {176, 79, 34, 60, 92, 11, 41, 114}
Initial head position = 50
Direction = left (We are moving from right to left)

Output:
Total number of seek operations = 226
Seek Sequence is
41
34
11
0
60
79
92
114
176

下表显示了使用SCAN服务请求的曲目的顺序。

因此,总寻道数计算如下:

= (50-41)+(41-34)+(34-11)
 +(11-0)+(60-0)+(79-60)
 +(92-79)+(114-92)+(176-114)
= 226

执行:
下面给出了SCAN的实现。请注意,距离用于存储磁头和当前磁道位置之间的绝对距离。 disk_size是磁盘的大小。左向量和右向量分别将所有请求轨迹存储在初始头部位置的左侧和右侧。

C++
// C++ program to demonstrate
// SCAN Disk Scheduling algorithm
 
#include 
using namespace std;
 
int size = 8;
int disk_size = 200;
 
void SCAN(int arr[], int head, string direction)
{
    int seek_count = 0;
    int distance, cur_track;
    vector left, right;
    vector seek_sequence;
 
    // appending end values
    // which has to be visited
    // before reversing the direction
    if (direction == "left")
        left.push_back(0);
    else if (direction == "right")
        right.push_back(disk_size - 1);
 
    for (int i = 0; i < size; i++) {
        if (arr[i] < head)
            left.push_back(arr[i]);
        if (arr[i] > head)
            right.push_back(arr[i]);
    }
 
    // sorting left and right vectors
    std::sort(left.begin(), left.end());
    std::sort(right.begin(), right.end());
 
    // run the while loop two times.
    // one by one scanning right
    // and left of the head
    int run = 2;
    while (run--) {
        if (direction == "left") {
            for (int i = left.size() - 1; i >= 0; i--) {
                cur_track = left[i];
 
                // appending current track to seek sequence
                seek_sequence.push_back(cur_track);
 
                // calculate absolute distance
                distance = abs(cur_track - head);
 
                // increase the total count
                seek_count += distance;
 
                // accessed track is now the new head
                head = cur_track;
            }
            direction = "right";
        }
        else if (direction == "right") {
            for (int i = 0; i < right.size(); i++) {
                cur_track = right[i];
                // appending current track to seek sequence
                seek_sequence.push_back(cur_track);
 
                // calculate absolute distance
                distance = abs(cur_track - head);
 
                // increase the total count
                seek_count += distance;
 
                // accessed track is now new head
                head = cur_track;
            }
            direction = "left";
        }
    }
 
    cout << "Total number of seek operations = "
         << seek_count << endl;
 
    cout << "Seek Sequence is" << endl;
 
    for (int i = 0; i < seek_sequence.size(); i++) {
        cout << seek_sequence[i] << endl;
    }
}
 
// Driver code
int main()
{
 
    // request array
    int arr[size] = { 176, 79, 34, 60,
                      92, 11, 41, 114 };
    int head = 50;
    string direction = "left";
 
    SCAN(arr, head, direction);
 
    return 0;
}


Java
// Java program to demonstrate
// SCAN Disk Scheduling algorithm
import java.util.*;
 
class GFG
{
 
static int size = 8;
static int disk_size = 200;
 
static void SCAN(int arr[], int head, String direction)
{
    int seek_count = 0;
    int distance, cur_track;
    Vector left = new Vector(),
                    right = new Vector();
    Vector seek_sequence = new Vector();
 
    // appending end values
    // which has to be visited
    // before reversing the direction
    if (direction == "left")
        left.add(0);
    else if (direction == "right")
        right.add(disk_size - 1);
 
    for (int i = 0; i < size; i++)
    {
        if (arr[i] < head)
            left.add(arr[i]);
        if (arr[i] > head)
            right.add(arr[i]);
    }
 
    // sorting left and right vectors
    Collections.sort(left);
    Collections.sort(right);
 
    // run the while loop two times.
    // one by one scanning right
    // and left of the head
    int run = 2;
    while (run-- >0)
    {
        if (direction == "left")
        {
            for (int i = left.size() - 1; i >= 0; i--)
            {
                cur_track = left.get(i);
 
                // appending current track to seek sequence
                seek_sequence.add(cur_track);
 
                // calculate absolute distance
                distance = Math.abs(cur_track - head);
 
                // increase the total count
                seek_count += distance;
 
                // accessed track is now the new head
                head = cur_track;
            }
            direction = "right";
        }
        else if (direction == "right")
        {
            for (int i = 0; i < right.size(); i++)
            {
                cur_track = right.get(i);
                 
                // appending current track to seek sequence
                seek_sequence.add(cur_track);
 
                // calculate absolute distance
                distance = Math.abs(cur_track - head);
 
                // increase the total count
                seek_count += distance;
 
                // accessed track is now new head
                head = cur_track;
            }
            direction = "left";
        }
    }
 
    System.out.print("Total number of seek operations = "
                        + seek_count + "\n");
 
    System.out.print("Seek Sequence is" + "\n");
 
    for (int i = 0; i < seek_sequence.size(); i++)
    {
        System.out.print(seek_sequence.get(i) + "\n");
    }
}
 
// Driver code
public static void main(String[] args)
{
 
    // request array
    int arr[] = { 176, 79, 34, 60,
                    92, 11, 41, 114 };
    int head = 50;
    String direction = "left";
 
    SCAN(arr, head, direction);
}
}
 
// This code is contributed by 29AjayKumar


Python3
# Python3 program to demonstrate
# SCAN Disk Scheduling algorithm
size = 8
disk_size = 200
 
def SCAN(arr, head, direction):
 
    seek_count = 0
    distance, cur_track = 0, 0
    left = []
    right = []
    seek_sequence = []
 
    # Appending end values
    # which has to be visited
    # before reversing the direction
    if (direction == "left"):
        left.append(0)
    elif (direction == "right"):
        right.append(disk_size - 1)
 
    for i in range(size):
        if (arr[i] < head):
            left.append(arr[i])
        if (arr[i] > head):
            right.append(arr[i])
 
    # Sorting left and right vectors
    left.sort()
    right.sort()
 
    # Run the while loop two times.
    # one by one scanning right
    # and left of the head
    run = 2
    while (run != 0):
        if (direction == "left"):
            for i in range(len(left) - 1, -1, -1):
                cur_track = left[i]
 
                # Appending current track to
                # seek sequence
                seek_sequence.append(cur_track)
 
                # Calculate absolute distance
                distance = abs(cur_track - head)
 
                # Increase the total count
                seek_count += distance
 
                # Accessed track is now the new head
                head = cur_track
             
            direction = "right"
     
        elif (direction == "right"):
            for i in range(len(right)):
                cur_track = right[i]
                 
                # Appending current track to seek
                # sequence
                seek_sequence.append(cur_track)
 
                # Calculate absolute distance
                distance = abs(cur_track - head)
 
                # Increase the total count
                seek_count += distance
 
                # Accessed track is now new head
                head = cur_track
             
            direction = "left"
         
        run -= 1
 
    print("Total number of seek operations =",
          seek_count)
 
    print("Seek Sequence is")
 
    for i in range(len(seek_sequence)):
        print(seek_sequence[i])
 
# Driver code
 
# request array
arr = [ 176, 79, 34, 60,
         92, 11, 41, 114 ]
head = 50
direction = "left"
 
SCAN(arr, head, direction)
 
# This code is contributed by divyesh072019


C#
// C# program to demonstrate
// SCAN Disk Scheduling algorithm
using System;
using System.Collections.Generic;
 
class GFG
{
 
static int size = 8;
static int disk_size = 200;
 
static void SCAN(int []arr, int head, String direction)
{
    int seek_count = 0;
    int distance, cur_track;
    List left = new List(),
                    right = new List();
    List seek_sequence = new List();
 
    // appending end values
    // which has to be visited
    // before reversing the direction
    if (direction == "left")
        left.Add(0);
    else if (direction == "right")
        right.Add(disk_size - 1);
 
    for (int i = 0; i < size; i++)
    {
        if (arr[i] < head)
            left.Add(arr[i]);
        if (arr[i] > head)
            right.Add(arr[i]);
    }
 
    // sorting left and right vectors
    left.Sort();
    right.Sort();
 
    // run the while loop two times.
    // one by one scanning right
    // and left of the head
    int run = 2;
    while (run-- >0)
    {
        if (direction == "left")
        {
            for (int i = left.Count - 1; i >= 0; i--)
            {
                cur_track = left[i];
 
                // appending current track to seek sequence
                seek_sequence.Add(cur_track);
 
                // calculate absolute distance
                distance = Math.Abs(cur_track - head);
 
                // increase the total count
                seek_count += distance;
 
                // accessed track is now the new head
                head = cur_track;
            }
            direction = "right";
        }
        else if (direction == "right")
        {
            for (int i = 0; i < right.Count; i++)
            {
                cur_track = right[i];
                 
                // appending current track to seek sequence
                seek_sequence.Add(cur_track);
 
                // calculate absolute distance
                distance = Math.Abs(cur_track - head);
 
                // increase the total count
                seek_count += distance;
 
                // accessed track is now new head
                head = cur_track;
            }
            direction = "left";
        }
    }
 
    Console.Write("Total number of seek operations = "
                        + seek_count + "\n");
    Console.Write("Seek Sequence is" + "\n");
    for (int i = 0; i < seek_sequence.Count; i++)
    {
        Console.Write(seek_sequence[i] + "\n");
    }
}
 
// Driver code
public static void Main(String[] args)
{
 
    // request array
    int []arr = { 176, 79, 34, 60,
                    92, 11, 41, 114 };
    int head = 50;
    String direction = "left";
 
    SCAN(arr, head, direction);
}
}
 
// This code is contributed by 29AjayKumar


Javascript


输出:
Total number of seek operations = 226
Seek Sequence is
41
34
11
0
60
79
92
114
176