[操做系統]設備分配中的數據結構:設備控制表(DCT)、控制器控制表(COCT)、通道控制表(CHCT)和系統設備表(SDT)

在多道程序環境下,系統中的設備供全部進程共享。爲防止諸進程對系統資源的無序競爭,特規定系統設備不容許用戶自行使用,必須由系通通一分配。每當進程向系統提出I/O請求時,只要是可能和安全的,設備分配程序便按照必定的策略,把設備分配給請求用戶(進程)。c++

在有的系統中,爲了確保在CPU與設備之間能進行通訊,還應分配相應的控制器和通道。算法

設備分配中的數據結構

---- 在進行設備分配時,一般都須要藉助於一些表格的幫助。在表格中記錄了相應設備或控制器的狀態及對設備或控制器進行控制所需的信息。安全

在進行設備分配時所需的數據結構(表格)由:設備控制表(DCT)、控制器控制表(COCT)、通道控制表(CHCT)和系統設備表(SDT)等。數據結構

設備控制表(DCT)

系統爲每個設備都配置了一張設備控制表,用於記錄本設備的狀況:函數

----- 設備類型:type、設備標識符:deviceid、設備狀態:等待/不等待 忙/閒、指向控制器表的指針、重複執行次數或時間、設備隊列的隊首指針。ui

設備控制表中,除了有用於指示設備類型的字段type和設備標識字段deviceid外,還應含有下列字段:設計

----- 設備隊列隊首指針。凡因請求本設備而未獲得知足的進程,其PCB都應按照必定的策略排成一個隊列,稱該隊列爲設備請求隊列或設備隊列。指針

----- 設備狀態。當設備自身正處於使用狀態時,應將設備的忙/閒標誌置「1」。若與該設備相鏈接的控制器或通道正忙,也不能啓動該設備,此時應將設備的等待標誌置「1」。code

----- 與設備鏈接的控制器表指針。該指針指向與該設備所鏈接的控制器的控制表,在設備到主機之間具備多條通路的狀況下,一個設備將與多個控制器相鏈接。此時,在DCT中還應設置多個控制器表指針。排序

----- 重複執行次數。因爲外部設備在傳送數據時,較易發生數據傳送錯誤,於是在許多系統中,若是發生傳送錯誤,並不當即認爲傳送失敗,而是

令它從新傳送,並由系統規定設備在工做中發生錯誤時應重複執行的次數。

控制器控制表、通道控制表和系統設備表

1)控制器控制表(COCT,Controller control table)。系統爲每個控制器都設置了一張用於記錄本控制器狀況的控制器控制表。其中記錄了:

     >控制器標識符-controllerid、控制器狀態-忙/閒、與控制器鏈接的通道表指針、控制器隊列的隊首指針、控制器隊列的隊尾指針。

2)通道控制表(CHCT,Channel control table)。每一個通道都配有一張通道控制表。其中記錄了:

    > 通道標識符-channelid、通道狀態-忙/閒、與通道鏈接的控制器表的指針通道隊列的隊首指針、通道隊列的隊尾指針。

3)系統設備表(SDT,System device table)。這是系統範圍的數據結構,其中記錄了系統中所有設備的狀況。每一個設備佔一個表目,其中包括有

     >設備類型、設備標識符、設備控制表及設備驅動程序的入口等項。

設備分配時應考慮的因素

設備的固有屬性

---- 在分配設備時,首先應考慮與設備分配有關的設備屬性。設備的固有屬性可分紅三種:獨佔性,指這種設備在一段時間內只容許一個進程獨佔,即「臨界資源」;共享性,指這種設備容許多個進程同時共享;可虛擬性,設備自己雖是獨佔設備,但通過某種技術處理,能夠把它改形成虛擬設備。

根據設備的固有屬性應採起不一樣的分配策略:
1)獨佔設備。對於獨佔設備,應採用獨享分配策略,即將一個設備分配給某進程後,便由該進程獨佔,直至該進程完成或釋放該設備,而後系統才能再將該設備分配給其餘進程使用。缺點:設備得不到充分利用,並且還可能引發死鎖。
2)共享設備。對於共享設備,可同時分配給多個進程使用,此時需注意對這些進程訪問該設備的前後次序進行合理的調度。
3)可虛擬設備。因爲可虛擬設備是指一臺物理設備在採用虛擬技術後,可變成多臺邏輯上的虛擬設備,於是說,一臺可虛擬設備是可共享的設備,
能夠將它同時分配給多個進程使用,並對訪問該(物理)設備的前後次序進行控制。

設備分配算法

---- 對設備進行分配的算法,與進程調度的算法有些類似之處,但前者相對簡單,一般只採用如下兩種分配算法:
1)先來先服務。當有多個進程對同一設備提出I/O請求時,該算法是根據諸進程對某設備提出請求的前後次序,將這些進程排成一個設備請求隊列,設備分配程序老是把設備首先分配給隊首進程。
2)優先級高者優先。在進程調度中的這種策略,是優先權高的進程優先得到處理機。若是對這種高優先權進程所提出的I/O請求也賦予高優先權,顯然有助於這種進程儘快完成。

在利用該算法造成設備隊列時,將優先權高的進程排在設備隊列前面,而對於優先級相同的I/O請求,則按先來先服務原則排隊。

設備分配時的安全性

---- 從進程運行的安全性考慮,設備分配有如下兩種方式。
1)安全分配方式。在這種分配方式中,每當進程發出I/O請求時,便進入阻塞狀態,直到其I/O操做完成時才被喚醒。
在採用這種分配策略時,一旦進程已經請求(得到)某種設備(資源)後便阻塞,使該進程不可能再請求其餘任何資源,所以,這種分配方式已經摒棄了形成死鎖的四個必要條件之一的"請求和保持"條件,從而使設備分配是安全的。缺點:進程進展緩慢,即CPU與I/O設備是串行工做的。

2)不安全分配方式。在這種分配方式中,進程在發出I/O請求後仍繼續運行,須要時又發出第二個I/O請求、第三個I/O請求等。僅當進程所請求的設備已被另外一進程佔用時,請求進程才進入阻塞狀態。這種分配方式的優勢是:一個進程可同時操做多個設備,使進程推動迅速。

缺點:分配不安全,由於它可能具有「請求和保持」條件,從而可能形成死鎖。所以,在設備分配程序中,還應再增長一個功能,以用於對本次的設備分配是否會發生死鎖進行安全性計算,僅當計算結果說明分配是安全的狀況下才進行設備分配。

獨佔設備的分配程序

基本的設備分配程序

---- 當某進程提出I/O請求後,系統的設備分配程序可按下述步驟進行設備分配:

1)分配設備

-- 首先根據I/O請求中的物理設備名,查找系統設備表(SDT),從中找出該設備的DCT(設備分配表),再根據DCT中的設備狀態字段,可知

該設備是否正忙。若忙,便將請求I/O進程的PCB掛在設備隊列上;不然,便按照必定的算法來計算本次設備分配的安全性。若是不會致使系統

進入不安全狀態,便將設備分配給請求進程;不然,仍將其PCB插入設備等待隊列。

2)分配控制器

-- 在系統把設備分配給請求I/O的進程後,再到其DCT(指向控制器表的指針)中找出與該設備鏈接的控制器的COCT(控制器控制表),從COCT

的狀態字段中可知該控制器是否忙碌。若忙,便將請求I/O進程的PCB掛在該控制器的等待隊列上;不然,便將該控制器分配給進程。

3)分配通道

-- 經過COCT中與控制器鏈接的通道表指針,找到與該控制器鏈接的通道的CHCT(通道控制表),再根據CHCT內的狀態信息,可知該通道是否

忙碌。若忙,便將請求I/O的進程掛在該通道的等待隊列上;不然,將該通道分配給進程。

-- 只有在設備、控制器和通道三者都分配成功時,此次的設備分配纔算成功。而後,即可啓動該I/O設備進行數據傳送。

設備分配程序的改進

---- 仔細研究上述基本的設備分配程序後能夠發現:

進程是以物理設備名來提出I/O請求的;採用的是單通路的I/O系統結構,容易產生「瓶頸」現象。

爲此,應從如下兩方面對基本的設備分配程序加以改進,以使獨佔設備的分配程序具備更強的靈活性,並提升分配的成功率。

1)增長設備的獨立性

-- 爲了得到設備的獨立性,進程應使用邏輯設備名請求I/O。這樣,系統首先從SDT中找出第一個該類設備的DCT。

若該設備忙,又查找第二個該類設備的DCT,僅當全部該類設備都忙時,才把進程掛在該類設備的等待隊列上;

而只要有一個該類設備可用,系統便進一步計算分配該類設備的安全性。

2)考慮多通路狀況

-- 爲了防止在I/O系統中出現「瓶頸」現象(通道不足),一般都採用多通路的I/O系統結構。

此時對控制器和通道的分配一樣要通過幾回反覆,即若設備(控制器)所鏈接的第一個控制器(通道)忙時,應查看其所鏈接的第二個控制器(通道),

僅當全部的控制器(通道)都忙時,這次的控制器(通道)分配纔算失敗,才把進程掛在控制器(通道)的等待隊列上。

而只要有一個控制器(通道)可用,系統即可將它分配給進程。



代碼實現:

  • 結構體聲明
struct sdt//系統設備表
{
    char name;//設備名稱
    char type;//設備類型
    struct sdt *next;
};

struct block//阻塞設備
{
    char pname;//申請設備進程名
    char ename;//設備名
    struct block *next;
};

struct chct//通道
{
    char name;//通道名稱
    int  state;//通道狀態
    struct block *next;//通道被佔用形成的阻塞隊列
};

struct coct//控制器表
{
    char name;//控制器名稱
    int state;//控制器狀態
    struct chct *chct;//設備通道
    struct block *next;//控制器被佔用形成的阻塞隊列
};

struct dct//設備控制表
{
    int state; //設備狀態
    struct sdt *sdt;//系統設備
    struct coct *coct;//設備控制器
    struct block *next;//設備被佔用形成的阻塞隊列
};
  • 定義
sdt *s[20];//設備

dct *d[20];//設備控制

coct *co[20];//控制器

chct *ch1,*ch2;//通道1,通道2

block *b;

int e=4;//設備數,初始爲4

int c=3;//控制器數,初始爲3
  • 初始化
void init()//初始化
{
    for(int i=0;i<4;i++)
    {
        s[i]=new(sdt);
        d[i]=new(dct);
        d[i]->state=0;
        d[i]->sdt=s[i];
        d[i]->next=new(block);
    d[i]->next->next=NULL;
    }
  s[0]->name='k';
    s[1]->name='m';
    s[2]->name='t';
    s[3]->name='p';
    s[0]->type='i';
    s[1]->type='i';
    s[2]->type='o';
    s[3]->type='o';

    for(int i=1;i<4;i++)
    {
        co[i]=new(coct);
        co[i]->state=0;
        co[i]->next=new(block);
        co[i]->next->next=NULL;
    }
  co[1]->name='1';
    co[2]->name='2';
    co[3]->name='3';

    ch1=new (chct);
    ch2=new (chct);
    ch1->name='1';
    ch1->state=0;
    ch1->next=new(block);
    ch1->next->next=NULL;
    ch2->name='2';
    ch2->state=0;
    ch2->next=new(block);
    ch2->next->next=NULL;

    co[1]->chct=ch1;
    co[2]->chct=ch2;
    co[3]->chct=ch2;

    d[0]->coct=co[1];
    d[1]->coct=co[1];
    d[2]->coct=co[2];
    d[3]->coct=co[3];
}

增長設備

void add()
{
    int i;
    char a;
    char b;
    cout<<"設備名稱:"<<endl;
    cin>>a;
    cout<<"設備類型:"<<endl;
    cin>>b;
    for(i=0;i<e;i++)
        if(d[i]->sdt->name==a)
            cout<<"設備已存在!"<<endl;
    if(i==e)
    {
    s[e]=new(sdt);
    d[e]=new(dct);
    s[e]->name=a;
    s[e]->type=b;
    d[e]->sdt=s[e];
    d[e]->state=0;
    d[e]->next=new(block);
    d[e]->next->next=NULL;
    e++;
    cout<<"是否新建控制器?(y/n)"<<endl;
    cin>>a;
    if(a=='y')
    {
        char g;
        int flag=0;
        cout<<"請輸入新增控制器名稱:"<<endl;
        cin>>g;
        if(flag==0)
        {
            for(int k=1;k<=c;k++)
                if(co[k]->name==g)
                {
                    flag=1;
                    cout<<"該控制器已存在,請從新輸入!"<<endl;
                    cin>>g;
                }
        }
        co[c+1]=new(coct);
        co[c+1]->name=g;
        co[c+1]->state=0;
        co[c+1]->next=new(block);
        co[c+1]->next->next=NULL;
        d[e-1]->coct=co[c+1];
        c++;
        cout<<"請選擇通道(1/2)"<<endl;
        char f;
        cin>>f;
        if(f=='1')
            co[c]->chct=ch1;
        if(f=='2')
            co[c]->chct=ch2;

        cout<<"設備添加成功!"<<endl;
    }
    else if(a=='n')
    {
        cout<<"當前已存在的控制器有:"<<endl;
        for(int i=1;i<=c;i++)
            cout<<co[i]->name<<endl;
        cout<<"輸入選擇的控制器名稱:"<<endl;
        char cz;
        cin>>cz;
        for(int j=1;j<=c;j++)
        {
            if(cz==co[j]->name)
            {
                cout<<"設備添加成功!"<<endl;
                d[e-1]->coct=co[j];
            }
        }
    }
    }
}

刪除設備

void del()
{
    int b;
    block *p;
    cout<<"設備名稱:"<<endl;
    char c;
    cin>>c;
    for(int i=0;i<e;i++)
    {
        if(d[i]->sdt->name==c)
        {
            if(d[i]->state==1)
                cout<<"用戶進程正在使用設備,沒法刪除!"<<endl;
            else
            if(d[i]->next->next!=NULL)//設備阻塞隊列不空
            {
                p=d[i]->next->next;
                for(;p->ename!=c&&p->next!=NULL;)
                    p=p->next;
                    cout<<"用戶進程"<<p->pname<<"等待使用設備,沒法刪除!"<<endl;
            }
            else
            if(d[i]->coct->next->next!=NULL)//控制器阻塞隊列不空
            {
                p=d[i]->coct->next->next;
                for(;p->ename!=c&&p->next!=NULL;)
                    p=p->next;
                    cout<<"用戶進程"<<p->pname<<"等待使用設備,沒法刪除!"<<endl;
            }
            else
            if(d[i]->coct->chct->next->next!=NULL)//通道阻塞隊列不空
            {
                p=d[i]->coct->chct->next->next;
                for(;p->ename!=c&&p->next!=NULL;)
                    p=p->next;
                    cout<<"用戶進程"<<p->pname<<"等待使用設備,沒法刪除!"<<endl;
            }
            else
            {
                cout<<"設備刪除成功!"<<endl;
                char coc=d[i]->coct->name;
                for(int j=i;j<e;j++)
                    d[j]=d[j+1];
                e--;
                cout<<"刪除控制器(y/n)?"<<endl;
                char a;
                cin>>a;
                if(a=='y')
                {
                    for(b=0;b<e;b++)
                        if(d[b]->coct->name==coc)
                            cout<<"控制器"<<coc<<"正在使用,沒法刪除!"<<endl;
                    if(b==e-1)
                    {
                        int j=0;
                        while(co[j]->name!=coc)
                            j++;
                        for(j;j<=c;j++)
                            co[j]=co[j+1];
                        c--;
                        cout<<"控制器刪除成功!"<<endl;
                    }
                    break;
                }
                else if(a=='n')
                    break;
            }
        }
    }
}

請求設備

void require()
{
    block *p;
    char ename,pname;
    cout<<"設備名稱:"<<endl;
    cin>>ename;
    cout<<"進程名稱:"<<endl;
    cin>>pname;
    for(int i=0;i<e;i++)
    {
        if(d[i]->sdt->name==ename &&d[i]->state==0 &&d[i]->coct->state==0 &&d[i]->coct->chct->state==0)
        {
            d[i]->state=1;
            d[i]->coct->state=1;
            d[i]->coct->chct->state=1;
            cout<<"申請成功!"<<endl;
        }
        else
        if(d[i]->sdt->name==ename&&d[i]->state==1)
        {
            cout<<"設備"<<d[i]->sdt->name<<"被佔用,進程阻塞!"<<endl;
            b=new(block);
            b->pname=pname;
            b->ename=ename;
            p=d[i]->next;
            while(p->next!=NULL)
                p=p->next;
            p->next=b;
            b->next=NULL;
        }
        else
        if(d[i]->sdt->name==ename &&d[i]->state==0 &&d[i]->coct->state==1)
        {
            cout<<"控制器"<<d[i]->coct->name<<"被佔用,進程阻塞!"<<endl;
            b=new(block);
            b->pname=pname;
            b->ename=ename;
            p=d[i]->coct->next;
            while(p->next!=NULL)
                p=p->next;
            p->next=b;
            b->next=NULL;
        }
        else
        if(d[i]->sdt->name==ename &&d[i]->state==0 &&d[i]->coct->state==0 &&d[i]->coct->chct->state==1)
        {
            cout<<"通道"<<d[i]->coct->chct->name<<"被佔用,進程阻塞!"<<endl;
            b=new(block);
            b->pname=pname;
            b->ename=ename;
            p=d[i]->coct->chct->next;
            while(p->next!=NULL)
                p=p->next;
            p->next=b;
            b->next=NULL;
        }
    }
}

回收設備

void callback()
{
    int i,j;
  char n;
    int b;
    cout<<"設備名稱:"<<endl;
    cin>>n;
    for(int i=0;i<e;i++)
    {
        if(d[i]->sdt->name==n)
        {
            if(d[i]->state==1)
            {
                cout<<"設備"<<d[i]->sdt->name<<"回收成功!"<<endl;
                d[i]->coct->state=0;
                d[i]->coct->chct->state=0;
                d[i]->state=0;
                if(d[i]->coct->chct->next->next!=NULL)
                {
                    cout<<"進程"<<d[i]->coct->chct->next->next->pname<<"已成功使用"<<d[i]->coct->chct->next->next->ename<<"設備!"<<endl;
                    for(b=0;b<e;b++)
                    {
                    if(d[i]->coct->chct->next->next->ename==d[b]->sdt->name)
                    {
                        d[b]->state=1;
                        break;
                    }
                }
                d[b]->coct->state=1;
                d[i]->coct->chct->state=1;
                block *p;
                p=d[i]->coct->chct->next;
                while(p->next->pname != d[i]->coct->chct->next->next->pname)
                    p=p->next;
                p->next = p->next->next;
                break;
            }
            if(d[i]->coct->next->next!=NULL)
            {

                cout<<"進程"<<d[i]->coct->next->next->pname<<"已成功使用"<<d[i]->coct->next->next->ename<<"設備!"<<endl;
                for(b=0;b<e;b++)
                {
                    if(d[i]->coct->next->next->ename==d[b]->sdt->name)
                        d[b]->state=1;
                }
                d[i]->coct->state=1;
                d[i]->coct->chct->state=1;
                block *q;
                q=d[i]->coct->next;
                while(q->next->pname != d[i]->coct->next->next->pname)
                    q=q->next;
                q->next = q->next->next;
                break;
            }
            if(d[i]->next->next!=NULL)
            {
                cout<<"進程"<<d[i]->next->next->pname<<"已成功使用"<<d[i]->next->next->ename<<"設備!"<<endl;
                for(int b=0;b<e;b++)
                {
                    if(d[i]->next->next->ename==d[b]->sdt->name)
                        d[b]->state=1;
                }

                d[i]->coct->state=1;
                d[i]->coct->chct->state=1;
                block *r;
                r=d[i]->next;
                while(r->next->pname != d[i]->next->next->pname)
                    r=r->next;
                r->next = r->next->next;
                break;
            }
            else
            {
                for(int j=0;j<e;j++)
                {
                    if(d[j]->coct->chct->next->next!=NULL)
                    {
                        cout<<"進程"<<d[j]->coct->chct->next->next->pname<<"已成功使用"<<d[j]->coct->chct->next->next->ename<<"設備!"<<endl;
                        d[j]->coct->state=1;
                        d[j]->coct->chct->state=1;
                        block *p;
                        p=d[j]->coct->chct->next;
                        while(p->next->pname != d[j]->coct->chct->next->pname)
                            p=p->next;
                        p->next = p->next->next;
                        break;
                    }
                    if(d[j]->coct->next->next!=NULL)
                    {
                        cout<<"進程"<<d[j]->coct->next->next->pname<<"已成功使用"<<d[j]->coct->next->next->ename<<"設備!"<<endl;
                        d[j]->state=1;
                        d[j]->coct->state=1;
                        d[j]->coct->chct->state=1;
                        block *q;
                        q=d[j]->coct->next;
                        while(q->next->pname != d[j]->coct->next->next->pname)
                            q=q->next;
                        q->next = q->next->next;
                        break;
                    }
                    if(d[j]->next->next!=NULL)
                    {
                        cout<<"進程"<<d[j]->next->next->pname<<"已成功使用"<<d[j]->next->next->ename<<"設備!"<<endl;
                        d[j]->state=1;
                        d[j]->coct->state=1;
                        d[j]->coct->chct->state=1;
                        block *r;
                        r=d[j]->next;
                        while(r->next->pname != d[j]->next->next->pname)
                            r=r->next;
                        r->next = r->next->next;
                        break;
                    }
                }
                if(j==e)
                    cout<<"無阻塞進程"<<endl;
            break;
            }
            }
            else
            {
                cout<<"設備閒置,無須回收!"<<endl;
                break;
            }
        }
    }
    if(i==e)
        cout<<"不存在該設備!"<<endl;
}

磁盤調度算法

//設備管理:磁盤調度
void FCFS(int array[],int m){
    int sum=0,j,i;
    double avg;
    cout<<"\n調度序列:"<<" ";
    for( i=0;i<m;i++)    {
        cout<<array[i]<<" ";
    }
    for(i=0,j=1;j<m;i++,j++)    {
        sum+=abs(array[j]-array[i]);
    }
    avg=sum/(m);
    cout<<"\n移動的總道數: "<<sum<<endl;
    cout<<"平均尋道時間: "<<avg<<endl;
    cout<<endl;
}

最短尋道時間優先算法

// 最短尋道時間優先算法
void ShortPath(int array[],int m)
{     int tmp;
    int k=1;
    int now,l,r,temp;
    int i,j;
    float sum=0,avg=0;
    for(i=0;i<m;i++)
        for(j=i+1;j<m;j++)
        {
            if(array[i]>array[j]) //將磁道號從小到大排序
            {
                temp=array[i];
                array[i]=array[j];
                array[j]=temp;
            }
        }
    cout<<"\n請輸入當前的磁道號:"; //輸入當前磁道號
    cin>>now;
    tmp=now;
    cout<<"最短尋道時間優先算法(SSTF)\n調度序列:";//輸出磁盤調度序列
    if(array[m-1]<=now)  //若被訪問的最大的磁道號小於當前的磁道號
        for(int x=m;x>0;x--)
        {
            sum+=now-array[x-1];
            cout<<array[x-1]<<" ";
            now=array[x-1];
        }
    
    else if(now<=array[0])  //若被訪問的最小的磁道號大於當前的磁道號
        for(int x=0;x<m;x++)
        {
            sum+=array[x]-now;
            cout<<array[x]<<" ";
            now=array[x];
        }
    //當前的磁道號的值在若全部被訪問的磁道號之間
    else{
        while(array[k]<=now) //肯定當前磁道在已排的序列中的位置
        {  k++;    }
        l=k-1;
        r=k;
        int count=m;
        while(count>0)
        {
            if(now==array[0])
                while(r<m)
                {
                    cout<<array[r]<<" ";
                    count--;
                    sum+=array[r]-now;
                    now=array[r];
                    r++;
                }
            else if(now==array[m-1])
                while(l>=0)
                {
                    cout<<array[l]<<" ";
                    count--;
                    sum+=now-array[l];
                    now=array[l];
                    l--;
                }
            else
            {
                if((now-array[l])<=(array[r]-now))
                {
                    cout<<array[l]<<" ";
                    count--;
                    sum+=now-array[l];
                    now=array[l];
                    l--;
                }
                else
                {
                    cout<<array[r]<<" ";
                    count--;
                    sum+=array[r]-now;
                    now=array[r];
                    r++;
                }
            }
        }
    }
    
    for(int i=0;i<m;i++)
    {
        if(tmp==array[i])
        {
            m=m-1;
            break;
        }
    }
    avg=sum/(m);
    cout<<endl<<"平均尋道長度:"<<avg<<endl<<endl;//輸出平均尋道長度
}

SCAN算法

//SCAN算法
void Elevator(int array[],int m)  //掃描算法
{     int temp;
    int k=1;
    int now,d,l,r;
    int i,j;
    float sum=0,avg=0;
    for(i=0;i<m;i++)
        for(j=i+1;j<m;j++)
        {
            if(array[i]>array[j]) //將磁道號從小到大排序
            {
                temp=array[i];
                array[i]=array[j];
                array[j]=temp;
            }
        }
    cout<<"\n請輸入當前的磁道號:";//輸入當前磁道號
    cin>>now;
    cout<<"請選擇當前磁頭的移動方向:"<<endl<<endl;
    cout<<" 1. 向磁道號增長方向"<<endl;
    cout<<" 0. 向磁道號減少方向"<<endl<<endl;
    cin>>d;          //給出磁頭移動方向
    cout<<"掃描算法(SCAN)\n調度序列:";
    if(array[m-1]<=now)   //在序列右方
    {
        for(i=m-1;i>=0;i--)
        { cout<<array[i]<<" ";
            sum+=now-array[i];
            now=array[i];
        }
    }
    else
    {
        if(array[0]>=now) //在序列左方
        {
            for(i=0;i<m;i++)
            {  cout<<array[i]<<" ";
                sum+=array[i]-now;
                now=array[i];
            }
        }
        else  //在序列中間
        {
            while(array[k]<now)  //肯定當前磁道在已排的序列中的位置
            {  k++;    }
            l=k-1;
            r=k;
            switch(d)
            {
                case 0:       //先向磁道號減少方向訪問
                {
                    while(l>=0)
                    {
                        cout<<array[l]<<" ";
                        sum+=now-array[l];
                        now=array[l];
                        l=l-1;
                    }
                    now=array[0];
                    for(j=r;j<m;j++)
                    {  cout<<array[j]<<" ";
                        sum+=array[j]-now;
                        now=array[j];
                    } break;
                }
                case 1:   //先向磁道號增長方向訪問
                {
                    while(r<m)
                    {
                        cout<<array[r]<<" ";
                        sum+=array[r]-now;
                        now=array[r];
                        r=r+1;
                    }
                    now=array[m-1];
                    for(j=l;j>=0;j--)
                    {  cout<<array[j]<<" ";
                        sum+=now-array[j];
                        now=array[j];
                    }break;
                }
                default: cout<<"輸入有誤"<<endl;
            }
        }
    }
    avg=sum/(m);
    cout<<endl<<"平均尋道長度:"<<avg<<endl<<endl;//輸出平均尋道長度
}
  • 功能菜單打印
void version_cipantiaodu() {
    cout<<endl<<endl;
    cout<<"      ┏━━━━━━━━━━━━━━━━━────────────────────━━━━━━┓"<<endl;
    cout<<"      ┃       設 備 管 理:磁 盤 調 度         ┃"<<endl;
    cout<<"      ┠───────────────────────────────────────────┨"<<endl;
    cout<<"      ┃          1.先來先服務                 ┃"<<endl;
    cout<<"      ┃          2.最短尋道時間優先           ┃"<<endl;
    cout<<"      ┃          3.SCAN算法                   ┃"<<endl;
    cout<<"      ┃          0.退出該算法                 ┃"<<endl;
    cout<<"      ┃                               ┃"<<endl;
    cout<<"      ┃       設計時間:20181228             ┃"<<endl;
    cout<<"      ┗━━━━━━━━━━━━━━━━━━━────────────────────━━━━┛"<<endl;
    cout<<endl<<endl;
}
  • 磁盤調度算法,從外部文件讀取 cidao.txt
void cipantiaodu(){
    int chioce;
    int flag=1;
    FILE *fp;
    int cidao[maxsize];
    int i=0,count;
    version_cipantiaodu();
    fp=fopen("cidao.txt","r+");
    if(fp==NULL){
        cout<<"can not find file!"<<endl;
        getchar();
        exit(0);
    }
    while(!feof(fp)){
        fscanf(fp,"%d",&cidao[i]);
        i++;
    }
    count=i-1;
    cout<<"磁盤訪問序列:"<<" ";
    for(i=0;i<count;i++){
        printf("%5d",cidao[i]);
    }
    cout<<endl;
    cout<<endl;
  • 選擇磁盤調度算法
while(flag){
        cout<<"請選擇:";
        cin>>chioce;
        switch(chioce){
            case 1:
                FCFS(cidao,count);
                break;
            case 2:
                ShortPath(cidao,count);
                break;
            case 3:
                Elevator(cidao,count);
                break;
            case 0:
                flag=0;
                system("clear");
                break;
            default:
                cout<<"選擇錯誤"<<endl<<endl;
        }
    }
    getchar();
}
  • 主菜單打印
void menu()
{
    cout<<"--------------------設備管理---------------------"<<endl;
    cout<<"                 a  添加設備"<<endl; 
    cout<<"                 d  刪除設備"<<endl; 
    cout<<"                 r  申請設備"<<endl; 
    cout<<"                 c  回收設備"<<endl;
    cout<<"                 s  設備狀態查看"<<endl;
        cout<<"                 p  磁盤調度"<<endl;
    cout<<"                 o  退出程序"<<endl;
    cout<<"-------------------------------------------------"<<endl;
}
  • 設備狀態查看
void play()
{
    cout<<"    "<<"設備名稱"<<"   "<<"類型"<<"    "<<"控制器"<<"    "<<"通道"<<endl;
    for(int i=0;i<e;i++)
        cout<<"       "<<d[i]->sdt->name<<"        "<<d[i]->sdt->type<<"        "<<d[i]->coct->name<<"       "<<d[i]->coct->chct->name<<endl;

}
  • main函數,功能調用
int main()
{
    init();
    menu();
    cout<<"請選擇:"<<endl;
    char c;
    cin>>c;
    while(c)
    {
    switch(c)
        {
        case 'a':
            add();
            break;
        case 'd':
            del();
            break;
        case 'r':
            require();
            break;
        case 'c':
            callback();
            break;
        case 's':
            play();
            break;
        case 'p':
            cipantiaodu();
            break;
        case 'o':
            exit(1);
        default:
            cout<<"輸入錯誤! ";
            break;
        }
        cout<<"請選擇:"<<endl;
        cin>>c;
    }
}
相關文章
相關標籤/搜索