1. 程式人生 > >作業系統-程序四個演算法實驗

作業系統-程序四個演算法實驗

實驗-程序描述與控制

一、實驗描述

磁碟排程在多道程式設計的計算機系統中,各個程序可能會不斷提出不同的對磁碟進行讀/寫操作的請求。由於有時候這些程序的傳送請求的速度比磁碟響應的還要快,因此我們有必要為每個磁碟裝置建立一個等待佇列,常用的磁碟排程演算法有以下四種:先來先服務演算法(FCFS ),最短尋道時間優先演算法(SSTF),掃描演算法(SCAN ),迴圈掃描演算法(CSCAN )。

通過程式設計,預先設定一個磁軌個數及磁碟訪問序列。分別採用先來先服務演算法(FCFS ),最短尋道時間優先演算法(SSTF),掃描演算法(SCAN ),迴圈掃描演算法(CSCAN ),通過結果,計算出四種演算法的平均尋道的長度,比較四種演算法之間的差異和優勢。

二、實驗程式碼

#include <iostream> 
#include <vector> 
#include <fstream> 
using namespace std; 
typedef vector<int> vInt; //向量,動態陣列
struct OrderItem 
{ 
    int Data; 
    bool IsVisited; 
}; 
typedef vector<OrderItem> Order; 
Order InitOrder; 
vInt TrackOrder; 
vInt MoveDistance; 
double AverageDistance;

void InitDate(int &num);
inline void Init(int disk); //行內函數(行內函數的程式碼會在任何呼叫它的地方展開)
void FCFS(int disk); 
void SSTF(int disk); 
void SCAN(int disk); 
void CSCAN(int disk); 
void Show(int disk);

int main() 
{ 
    int num; 
    InitDate(num); 
    char cmd; 
    do 
    { 
        cout<<"選擇演算法:\n"<<"1-FCFS,2-SSTF,3-SCAN,4-CSCAN:\t"; 
        int type;cin>>type; 
        switch(type) 
        {   
case 1:FCFS(num);break; 
            case 2:SSTF(num);break; 
            case 3:SCAN(num);break; 
            case 4:CSCAN(num);break; 
        } 
        Show(num); 
        cout<<"Continue? y or n?\t"; 
        cin>>cmd; 
    }while(cmd!='n'); 
    return 0; 
}

inline void Init(int disk) 
{ 
    TrackOrder.clear(); 
    MoveDistance.clear(); 
    for(int i = 0; i < disk; i++) 
    { 
        InitOrder[i].IsVisited = false; 
    } 
}

void InitDate(int &num) 
{ 
    //ifstream cin("data.txt"); 
    cout<<"輸入磁軌個數"; 
    cin>>num; 
    cout<<"磁碟訪問序列"; 
for(int i=0; i<num; i++)
{ 
        OrderItem oi; 
        cin>>oi.Data; 
        oi.IsVisited = false; 
        InitOrder.push_back(oi); 
    } 
}

void FCFS(int disk) 
{ 
    cout<<"輸入開始磁碟號"; 
    int start;cin>>start; 
    cout<<"FCFS:"<<endl; 
    int p = start; 
    Init(disk); 
    for(int i = 0 ; i < disk; i++ ) 
    { 
        TrackOrder.push_back(InitOrder[i].Data); 
        int t = InitOrder[i].Data-p; 
        MoveDistance.push_back(t>0?t:-t); 
        InitOrder[i].IsVisited = true; 
        p = InitOrder[i].Data; 
     } 
}

void SSTF(int disk) 
{ 
    cout<<"輸入開始磁碟號"; 
    int start;cin>>start; 
    cout<<"SSTF:"<<endl; 
    Init(disk); 
    int curp=0,dif=0; 
    int p = start; 
    for(int i = 0; i < disk; i++) 
    { 
        int temp = 0; 
        for(int j = 0 ; j < disk; j++) 
        { 
            if(InitOrder[j].IsVisited == false) 
            { 
                temp = p-InitOrder[j].Data>0? 
                p-InitOrder[j].Data:-(p-InitOrder[j].Data); 
                if(dif==0||temp<dif) 
                { 
                    dif = temp; 
                    curp = j;
} 
            } 
        } 
        InitOrder[curp].IsVisited = true; 
        TrackOrder.push_back(InitOrder[curp].Data); 
        MoveDistance.push_back(dif); 
        p = InitOrder[curp].Data; 
        dif = 0; 
     } 
}

void SCAN(int disk) 
{ 
    cout<<"輸入開始磁碟號"; 
    int start;cin>>start; 
    cout<<"選擇訪問方向:0-磁軌號遞增1-磁軌號遞減\t"; 
    int dir; cin>>dir; 
    cout<<"SSTF:"<<endl; 
    Init(disk); 
    int curp=0,dif=0,cdir=dir,max=InitOrder[0].Data,min=max; 
    for(int i =1; i<disk;i++) 
    { 
        if(max<InitOrder[i].Data) 
            max = InitOrder[i].Data; 
        if(min>InitOrder[i].Data) 
            min = InitOrder[i].Data; 
    } 
    int p = start; 
    for(int k = 0; k< disk; k++) 
    { 
        int temp = 0; 
        for(int j = 0 ; j < disk; j++) 
        { 
            
if(cdir==0&&p>InitOrder[j].Data||cdir==1&&p<InitOrder[j].Data) 
                continue; 
            if(InitOrder[j].IsVisited == false) 
            { 
                temp = p-InitOrder[j].Data>0? 
                p-InitOrder[j].Data:-(p-InitOrder[j].Data); 
                if(dif==0||temp<dif) 
                { 
                    dif = temp; 
                    curp = j; 
                }
} 
        } 
        if(dir==0&&InitOrder[curp].Data==max)cdir = 1; 
        if(dir==1&&InitOrder[curp].Data==min)cdir = 0; 
        InitOrder[curp].IsVisited = true; 
        TrackOrder.push_back(InitOrder[curp].Data); 
        MoveDistance.push_back(dif); 
        p = InitOrder[curp].Data; 
        dif = 0; 
    } 
}

void CSCAN(int disk) 
{ 
    cout<<"輸入開始磁碟號"; 
    int start;cin>>start; 
    cout<<"選擇訪問方向:0-磁軌號遞增1-磁軌號遞減\t"; 
    int dir; cin>>dir; 
    cout<<"CSSTF:"<<endl; 
    Init(disk); 
    int curp=0,dif=-1,max=InitOrder[0].Data,min=max,mmin=0,mmax=0; 
    for(int i =1; i<disk;i++)//找到磁軌序列中最小和最大的磁軌號及下標 
    { 
        if(max<InitOrder[i].Data) 
        { 
            max = InitOrder[i].Data; 
            mmax = i; 
        } 
        if(min>InitOrder[i].Data) 
        { 
            min = InitOrder[i].Data; 
            mmin=i; 
        } 
    } 
    int p = start;//p表示上一個訪問的磁軌號 
    for(int k = 0; k < disk; k++) 
    { 
        int temp = 0; 
        for(int j = 0 ; j < disk; j++)//查詢下一個要訪問的磁軌 
        { 
            
if(dir==0&&p>InitOrder[j].Data||dir==1&&p<InitOrder[j].Data) 
                continue; 
            if(InitOrder[j].IsVisited == false)//dir方向且未被訪問的項 
            {
temp = p-InitOrder[j].Data>0? 
                (p-InitOrder[j].Data):(InitOrder[j].Data-p); 
                if(dif==-1||temp<dif) 
                { 
                    dif = temp; 
                    curp = j;//找到下一個被訪問的磁軌 
                } 
            } 
        } 
        InitOrder[curp].IsVisited = true;//訪問 
        TrackOrder.push_back(InitOrder[curp].Data); 
        MoveDistance.push_back(dif); 
        p  = InitOrder[curp].Data; 
        //達到極限點 
        
if(dir==0&&InitOrder[curp].Data==max&&InitOrder[mmin].IsVisited==false) 
        { 
            //從最小項開始 
            TrackOrder.push_back(min); 
            InitOrder[mmin].IsVisited = true; 
            MoveDistance.push_back(p-TrackOrder[mmin]>=0? 
                p-TrackOrder[mmin]:TrackOrder[mmin]-p); 
            curp = mmin; 
        } 
        
if(dir==1&&InitOrder[curp].Data==min&&InitOrder[mmax].IsVisited==false) 
        { 
            TrackOrder.push_back(max); 
            InitOrder[mmax].IsVisited = true; 
            MoveDistance.push_back(p-TrackOrder[mmin]>=0? 
                p-TrackOrder[mmin]:TrackOrder[mmin]-p); 
            curp = mmax; 
        } 
        p = InitOrder[curp].Data; 
        dif = -1; 
    } 
}

void Show(int disk) 
{ 
    cout<<"被訪問的下一個磁軌號\t"<<"移動距離"<<endl; 
    int sum=0; 
    for(int i = 0 ; i <disk; i++) 
    { 
        sum+=MoveDistance[i];
cout<<"\t"<<TrackOrder[i]<<"\t\t  "<<MoveDistance[i]<<endl; 
    } 
    AverageDistance = (double)sum/disk; 
    cout<<"平均尋道長度:"<<AverageDistance<<endl; 
}