第一篇:電梯調度算法總結
1.傳統電梯調度算法
1.1先來先服務算法(FCFS)
先來先服務(FCFS-First Come First Serve)算法,是一種隨即服務算法,它不僅僅沒有對尋找樓層進行優化,也沒有實時性的特征,它是一種最簡單的電梯調度算法。它根據乘客請求乘坐電梯的先后次序進行調度。此算法的優點是公平、簡單,且每個乘客的請求都能依次地得到處理,不會出現某一乘客的請求長期得不到滿足的情況[12]。這種方法在載荷較輕松的環境下,性能尚可接受,但是在載荷較大的情況下,這種算法的性能就會嚴重下降,甚至惡化。人們之所以研究這種在載荷較大的情況下幾乎不可用的算法,有兩個原因:
(1)任何調度算法在請求隊列長度為1時,請求速率極低或相鄰請求的間隔為無窮大時使用先來先服務算法既對調度效率不會產生影響,而且實現這種算法極其簡單。
(2)先來先服務算法可以作為衡量其他算法的標準。
1.2最短尋找樓層時間優先算法(SSTF)
最短尋找樓層時間優先(SSTF-Shortest Seek Time First)[14]算法,它注重電梯尋找樓層的優化。最短尋找樓層時間優先算法選擇下一個服務對象的原則是最短尋找樓層的時間。這樣請求隊列中距當前能夠最先到達的樓層的請求信號就是下一個服務對象。在重載荷的情況下,最短尋找樓層時間優先算法的平均響應時間較短,但響應時間的方差較大,原因是隊列中的某些請求可能長時間得不到響應,出現所謂的“餓死”現象。
1.3掃描算法(SCAN)
掃描算法(SCAN)是一種按照樓層順序依次服務請求,它讓電梯在最底層和最頂層之間連續往返運行,在運行過程中響應處在于電梯運行方向相同的各樓層上的請求。它進行尋找樓層的優化,效率比較高,但它是一個非實時算法。掃描算法較好地解決了電梯移動的問題,在這個算法中,每個電梯響應乘客請求使乘客獲得服務的次序是由其發出請求的乘客的位置與當前電梯位置之間的距離來決定的,所有的與電梯運行方向相同的乘客的請求在一次電向上運行或向下運行的過程中完成,免去了電梯頻繁的來回移動[2]。掃描算法的平均響應時間比最短尋找樓層時間優先算法長,但是響應時間方差比最短尋找樓層時間優先算法小,從統計學角度來講,掃描算法要比最短尋找樓層時間優先算法穩定。
1.4 LOOK 算法
LOOK算法[18]是掃描算法的一種改進。對LOOK算法而言,電梯同樣在最底層和最頂層之間運行。但當LOOK算法發現電梯所移動的方向上不再有請求時立即改變運行方向,而掃描算法則需要移動到最底層或者最頂層時才改變運行方向。
1.5 SAFT 算法
SATF(Shortest Access Time First)[15,19]算法與SSTF算法的思想類似,唯一的區別就是SATF算法將SSTF算法中的尋找樓層時間改成了訪問時間。這是因為電梯技術發展到今天,尋找樓層的時間已經有了很大地改進,但是電梯的運行當中等待乘客上梯時間卻不是人為可以控制。SATF算法考慮到了電梯運行過程中乘客上梯時間的影響。實時電梯調度算法
2.1最早截止期優先調度算法
最早截止期優先(EDF-Earliest Deadline First)[16]調度算法是最簡單的實時電梯調度算法,它的缺點就是造成電梯任意地尋找樓層,導致極低的電梯吞吐率。它與FCFS調度算法類似,EDF算法是電梯實時調度算法中最簡單的調度算法。它響應請求隊列中時限最早的請求,是其它實時電梯調度算法性能衡量的基準和特例。
2.2 SCAN-EDF 算法
SCAN-EDF[16]算法是SCAN算法和EDF算法相結合的產物。SCAN-EDF算法先按照EDF算法選擇請求列隊中哪一個是下一個服務對象,而對于具有相同時限的請求,則按照SCAN算法服務每一個請求。它的效率取決于有相同deadline 的數目,因而效率是有限的。
2.3 PI 算法
PI(Priority Inversion)[16]算法將請求隊列中的請求分成兩個優先級,它首先保證高優先級隊列中的請求得到及時響應,再搞優先級隊列為空的情況下在相應地優先級隊列中的請求。
2.4 FD-SCAN 算法
FD-SCAN(Feasible Deadline SCAN)[17]算法首先從請求隊列中找出時限最早、從當前位置開始移動又可以買足其時限要求的請求,作為下一次SCAN的方向。并在電梯所在樓層向該請求信號運行的過程中響應處在與電梯運行方向相同且電梯可以經過的請求信號。這種算法忽略了用SCAN算法相應其它請求的開銷,因此并不能確保服務對象時限最終得到滿足。電梯調度的高水平研究
以上兩個小結介紹了幾種在目前本人的能力上能進行研究的、簡單的電梯調度算法。但是并不是說目前電梯調度只發展到這個層次。目前電梯的控制技術已經進入了電梯群控的時代。
隨著微機在電梯系統中的應用和人工智能技術的發展,智能群控技術得以迅速發展起來。由此,電梯的群控方面陸續發展出了一批新方法,包括:基于專家系統的電梯群控方法、基于模糊邏輯的電梯群控方法、基于遺產算法的電梯群控方法、基于勝景網絡的電梯群控方法和基于模糊神經網絡的電梯群控方法。4 電梯問題的需求分析
4.1 電梯的初始狀態
本人設置的電梯的初始狀態,是對住宅樓的電梯的設置。
(1)建筑共有21層,其中含有地下一層(地下一層為停車場及貨物運送場所)。
(2)建筑內部設有兩部電梯,編號分別為A梯、B梯。
(3)電梯內部有23個按鈕,其中包括開門按鈕、關門按鈕和樓層按鈕,編號為-1,1,2,3,4……20。
(4)電梯外部含有兩個按鈕,即向上運行按鈕和向下運行按鈕。建筑頂層與地下一層例外,建筑頂層只設置有向下運行按鈕,地下一層只設置有向上運行按鈕。
(5)電梯開關門完成時間設定為1秒。電梯到達每層后上下人的時間設定為8秒。電梯從靜止開始運行到下一層的時間設置為2秒,而運行中通過一層的時間為1秒。
(6)在凌晨2:00——4:30之間,如若沒有請求信號,A梯自動停在14層,B梯自動停在6層。
(7)當電梯下到-1層后,如果沒有請求信號,電梯自動回到1層
4.2 電梯按鈕功能
電梯內部的樓層按鈕:電梯內部對應每一個樓層的按鈕成為樓層按鈕,即本章第一結提到的編號為-1,1,2,3,4……20的按鈕。當乘客進入電梯后按下樓層按鈕,此按鈕顯示灰色,代表不可以用。這樣就表示乘客將要去往此層,電梯將開往相應層。當電梯到達該層后,按鈕恢復可以使用狀態。
電梯內部開門按鈕:當電梯達到乘客想要去往的某樓層后,乘客需要準備離開電梯,當電梯停穩后,乘客可以按下開門按鈕,電梯門將打開,讓用戶離開。如若電梯到了乘客曾經按下的樓層,但是無乘客按開門按鈕,電梯將自動在停穩后1秒后自動開門。
電梯內部關門按鈕:當所有想要乘坐電梯的乘客都進入電梯以后,準備讓電梯開始運行的時候,乘客需要按下關門按鈕,讓電梯門關閉,使電梯進入運行狀態。設置電梯的自動關門時間為8秒。
電梯外部向上按鈕:此按鈕表示上樓請求,當按下此按鈕時,如果電梯到達按下此按鈕的樓層,且電梯運行方向是向上的,那么電梯響將停下,并在電梯停穩之后自動開門,此請求被響應后,取消此請求信號。電梯外部向下按鈕:此按鈕表示下樓請求,當按下此按鈕時,如果電梯到達按下此按鈕的樓層,且電梯運行方向是向下的,那么電梯響將停下,并在電梯停穩之后自動開門,此請求被響應后,取消此請求信號。
第二篇:電梯優先調度算法
電梯優先調度算法
電梯調度算法(ms InterView)
移臂調度算法包括以下四種:
1)先來先服務算法:根據訪問者提出訪問請求的先后次序來決定執行次序。
2)最短尋找時間優先調度算法:從等待的訪問者中挑選尋找時間最短的那個請求執行,而不管訪問者的先后次序。
3)電梯調度掃描算法:從移動臂當前位置沿移動方向選擇最近的那個柱面的訪問者來執行,若該方向上無請求訪問時,就改變移動方向再選擇。
4)單向掃描調度算法:從0柱面開始往里單向掃描,掃到哪個執行哪個。
*/
// t1.cpp : 定義控制臺應用程序的入口點。
//
#include “stdafx.h” #include“math.h” #include“stdlib.h” #include“string.h” struct Head {
int nPosition;bool bVisited;};
void Visit(struct Head *pHead){
printf(“visite cy:%dn”,pHead->nPosition);pHead->bVisited=true;} int ReadInputKeyboard(struct Head *pHead,int *pCurrentPosition,int nMaxNumber){ int i;
printf(“please input Current position:”);scanf(“%d”,pCurrentPosition);
printf(“please input will visit position:”);for(i=0;i scanf(“%d”,&pHead[i].nPosition);pHead[i].bVisited=false;if(pHead[i].nPosition<0)break;} return i;} int ReadInputFile(struct Head *pHead,int *pCurrentPosition,int nMaxNumber){ int i; char szFileName[256],*q,*p,szTemp[20];printf(“please input filename:”);scanf(“%s”,szFileName); FILE *pFile=fopen(szFileName,“r”);if(pFile==NULL){ printf(“open file %s error”,szFileName);return-1;} for(i=0;!feof(pFile)&&i p=szFileName;fgets(p,256,pFile); while(q=strchr(p,',')){ memset(szTemp,0,sizeof(szTemp)*sizeof(char));strncpy(szTemp,p,q-p);p=q+1;if(i==0) *pCurrentPosition=atoi(szTemp);else { pHead[i-1].nPosition=atoi(szTemp);pHead[i-1].bVisited=false;} i++;} memset(szTemp,0,sizeof(szTemp)*sizeof(char));pHead[i-1].nPosition=atoi(p);pHead[i-1].bVisited=false;//i++; } fclose(pFile);return i;} int FifoVisit(int nCurrentPosition,struct Head *pHead,int nNumber){ //先來先服務 int nHaveVisited=0;int nMoveDistance=0;int i;while(nHaveVisited for(i=0;i if(pHead[i].bVisited)continue; Visit(&pHead[i]);nHaveVisited++; nMoveDistance+=abs(nCurrentPosition-pHead[i].nPosition);nCurrentPosition=pHead[i].nPosition;} } printf(“the sum of move distance:%dn”,nMoveDistance);return nMoveDistance;} int SsfoVisit(int nCurrentPosition,struct Head *pHead,int nNumber){ // 最短尋找時間優先 int nHaveVisited=0;int nMoveDistance=0;int nMinDistance=0;int nMinIndex=0;int i; while(nHaveVisited nMinDistance=0xffff;nMinIndex=0;//找最小值 for(i=0;i if(pHead[i].bVisited)continue; if(nMinDistance>abs(pHead[i].nPosition-nCurrentPosition)){ nMinDistance=abs(pHead[i].nPosition-nCurrentPosition);nMinIndex=i;} } //訪問 Visit(&pHead[nMinIndex]);nHaveVisited++; nMoveDistance+=nMinDistance; nCurrentPosition=pHead[nMinIndex].nPosition;} printf(“the sum of move distance:%dn”,nMoveDistance);return nMoveDistance;} int DtVisit(int nCurrentPosition,bool bOut,struct Head *pHead,int nNumber){ //電梯調度算法 int nHaveVisited=0;int nMoveDistance=0;int nMinDistance=0;int nMinIndex=0;int i; while(nHaveVisited nMinDistance=0xffff;nMinIndex=0;//找最小值 for(i=0;i if(pHead[i].bVisited)continue; if(bOut&&pHead[i].nPosition if(nMinDistance>abs(pHead[i].nPosition-nCurrentPosition)){ nMinDistance=abs(pHead[i].nPosition-nCurrentPosition);nMinIndex=i;} } } if(nMinDistance==0xffff){ bOut=!bOut;continue;} //訪問 Visit(&pHead[nMinIndex]);nHaveVisited++; nMoveDistance+=nMinDistance; nCurrentPosition=pHead[nMinIndex].nPosition;} printf(“the sum of move distance:%dn”,nMoveDistance);return nMoveDistance;} int DxVisit(int nCurrentPosition,struct Head *pHead,int nNumber){ //單向調度算法 int nHaveVisited=0;int nMoveDistance=0;int nMinDistance=0;int nMinIndex=0;int i;while(nHaveVisited nMinDistance=0xffff;nMinIndex=0;//找最小值 for(i=0;i if(pHead[i].bVisited)continue; if(pHead[i].nPosition>nCurrentPosition){ if(nMinDistance>abs(pHead[i].nPosition-nCurrentPosition)){ nMinDistance=abs(pHead[i].nPosition-nCurrentPosition);nMinIndex=i;} } } if(nMinDistance==0xffff){ nMoveDistance+=199-nCurrentPosition;nCurrentPosition=0;continue;} //訪問 Visit(&pHead[nMinIndex]);nHaveVisited++; nMoveDistance+=nMinDistance; nCurrentPosition=pHead[nMinIndex].nPosition;} printf(“the sum of move distance:%dn”,nMoveDistance);return nMoveDistance;} int main(int argc, char* argv[]){ //p114 struct Head mylist[20];//={98,false,183,false,37,false,122,false,14,false,124,false,65,false,67,false}; //int nCurrentPosition=53; //int nRealNumber=8; int nCurrentPosition=0; int nRealNumber=ReadInputFile(mylist,&nCurrentPosition,20);// FifoVisit(nCurrentPosition,mylist,nRealNumber); // SsfoVisit(nCurrentPosition,mylist,nRealNumber); //DtVisit(nCurrentPosition,false,mylist,nRealNumber); DxVisit(nCurrentPosition,mylist,nRealNumber); return 0;} 1.實驗題目: 磁盤調度算法。 建立相應的數據結構; 在屏幕上顯示磁盤請求的服務狀況; 將一批磁盤請求的情況存磁盤文件,以后可以讀出并重放; 計算磁頭移動的總距離及平均移動距離; 支持算法:FIFO、SSTF、SCAN、CSCAN; 2.設計目的: 調度磁盤I/O請求服務,采用好的方式能提高訪問時間和帶寬。本實驗通過編程對磁盤調度算法的實現,加深對算法的理解,同時通過用C++語言編寫程序實現這些算法,并在windos平臺上實現,更好的掌握操作系統的原理以及實現方法,提高綜合運用專業課知識的能力。 3.任務及要求 3.1 設計任務 編程實現下述磁盤調度算法,并求出每種算法的平均尋道長度: 1、先來先服務算法(FCFS) 2、最短尋道時間算法(SSTF) 3、掃描算法(SCAN) 4、循環掃描算法(CSCAN) 3.2 設計要求 對用戶指定的磁盤調度請求序列,基于以上四種算法,實現各自的調度順序并輸出,同時計算出各種算法下的平均尋道長度。 4.算法及數據結構 4.1算法的總體思想 queue[n] 為請求調度序列,diskrode為磁盤磁道數,headstarts為正在調度的磁道 ①先來先服務算法(FCFS)按queue[n]數組的順序進行磁盤調度,將前一個調度磁道與下一個調度磁道的差值累加起來,得到總的尋道長度,再除以n得到平均尋道長度。 ②最短尋道時間優先算法(SSTF)將queue[n]進行由小到大的排序,首先定位當前調度磁headstarts在queue[n]的位置,通過循環語句找出離起始磁頭最短的位置。 ③掃描算法(SCAN) 將queue[n]進行由小到大的排序,首先定位當前調度磁headstarts在queue[n]的位置,然后在此位置按給定的方向遍歷queue[n],當道端點(queue[0]或queue[n-1])時,再在定位處反向遍歷到另一端。當調度磁道不在queue端點時,總的尋道長度為為前一個磁道與后一個磁 道差值的累加,當到達端點且queue[n]未全調度時,總尋道長度加上端點值再加上下一個調度磁道的值,再按前面的算法進行,直到磁道全部都調度完畢,得到總的尋道長度,除以n得到平均尋道長度。 ④循環掃描算法(CSCAN)將queue[n]進行由小到大的排序,首先定位當前調度磁headstarts在queue[n]的位置,然后在此位置按給定的方向遍歷queue[n],當道端點(queue[0]或queue[n-1])時,反向到另一端點再以此方向進行遍歷,直到queue[n]中所有都調度完。當調度磁道不在queue端點時,總的尋道長度為為前一個磁道與后一個磁道差值的累加,當到達端點且queue[n]未全調度時,總尋道長度加上端點值再加上磁盤磁道總長度,再加上下一個調度磁道的值,再按前面的算法進行,直到磁道全部都調度完畢,得到總的尋道長度,除以n得到平均尋道長度。 5、源代碼: #include 1、先來先服務算法(FCFS)**********”< cout<<“****** 2、最短尋道時間優先算法(SSTF)**********”< cout<<“****** 3、掃描算法(SCAN)**********”< cout<<“****** 4、循環掃描算法(CSCAN)**********”< cout<<“****** 5、退出 **********”< /*======================初始化序列=======================*/ void init(int queue[],int queue_copy[],int n){ int i;for(i=0;i //對當前正在執行的磁道號進行定位,返回磁道號小于當前磁道中最大的一個 int fix(int queue[], int n, int headstarts){ int i =0;while(i /* ====================以下是FCFS算法==================*/ void FCFS(int queue[],int n,int diskrode,int headstarts)//queue是請求調度序列,n為其個數,diskroad為磁盤磁道數,headstarts為正在調度的磁道 { cout<<“************以下為FCFS調度算法***********”< /*=====================SSTF算法====================*/ void SSTF(int queue[], int n, int diskrode, int headstarts){ int k=1;int l,r;int i,j,count=0;queue =bubble(queue,n);cout<<“************以下為SSTF調度算法***********”< -headstarts)){ cout< /*======================以下是SCAN算法====================*/ void SCAN(int queue[], int n, int diskrode, int headstarts){ int direction, i, fixi;cout<<“***********以下是SCAN調度算法*************”< /*======================以下是CSCAN算法====================*/ void CSCAN(int queue[],int n,int diskrode,int headstarts){ int direction,i,fixi;cout<<“***********以下是CSCAN調度算法*************”< void main(){ int n, i, diskrode, headstarts;//n表示調度磁盤請求序列queue的長度,diskrode表示磁盤磁道的個數,headstarts表示目前正在調度的磁道; cout<<“請輸入磁盤的總磁道數:”< if(menux ==2)SSTF(queue,n,diskrode,headstarts); if(menux ==3)SCAN(queue,n,diskrode,headstarts);if(menux ==4)CSCAN(queue,n,diskrode,headstarts);if(menux ==5)cout<<“程序結束,謝謝使用!”< 沈陽理工大學課程設計專用紙 Noi 目 錄 1 課程設計目的及要求……………………………………………………錯誤!未定義書簽。2 相關知識…………………………………………………………………錯誤!未定義書簽。3 題目分析…………………………………………………………………2 4 概要設計…………………………………………………………………2 4.1 先來先服務(FCFS)的設計思想……………………………….2 4.2 最短尋道時間優先調度(SSTF)的設計思想…………………..2 4.3 掃描算法(SCAN)的設計思想…………………………………2 4.4 循環掃描(CSCAN)的設計思想………………………………..2 5 代碼及流程………………………………………………………………3 5.1 流程圖……………………………………………………………...3 5.2 源代碼……………………………………………………………...8 6 運行結果…………………………………………………………………16 7 設計心得…………………………………………………………………19 參考文獻…………………………………………………………………………19 沈陽理工大學 沈陽理工大學課程設計專用紙 No1 1 課程設計目的及要求 設計目的:加深對操作系統原理的進一步認識,加強實踐動手能力和程序開發能力的培養,提高分析問題解決問題的能力,培養合作精神,以鞏固和加深磁盤調度的概念。操作系統是一門工程性很強的課程,它不僅要求學生掌握操作系統的工作原理和理論知識,也要求學生的實際動手能力,以加深對所學習內容的理解,使學生熟練地掌握計算機的操作方法,使用各種軟件工具,加強對課程內容的理解。這次課程設計,就是通過模擬磁臂調度來加深對操作系統中磁臂調度概念的理解。使學生熟悉磁盤管理系統的設計方法;加深對所學各種磁盤調度算法的了解及其算法的特點。 設計要求:編程序實現下述磁盤調度算法,并求出每種算法的平均尋道長度;要求設計主界面可以靈活選擇某算法,且以下算法都要實現 1、先來先服務算法(FCFS) 2、最短尋道時間優先算法(SSTF) 3、掃描算法(SCAN) 4、循環掃描算法(CSCAN)相關知識 數據結構:數組 now:當前磁道號; array[]:放置磁道號的數組; void FCFS(int array[],int m)先來先服務算法(FCFS)void SSTF(int array[],int m)最短尋道時間優先算法(SSTF)void SCAN(int array[],int m)掃描算法(SCAN)void CSCAN(int array[],int m)循環掃描算法(CSCAN)磁盤調度:當有多個進程都請求訪問磁盤時,采用一種適當的驅動調度算法,使各進程對磁盤的平均訪問(主要是尋道)時間最小。目前常用的磁盤調度算法有:1)閑來先服務2)最短尋道時間優先3)掃描算法4)循環掃描算法等 沈陽理工大學 沈陽理工大學課程設計專用紙 No2 3 題目分析 選擇一個自己熟悉的計算機系統和程序設計語言模擬操作系統基本功能的設計方法及其實現過程 完成各分項功能。在算法的實現過程中,要求可決定變量應是動態可變的;同時模塊應該有一個合理的輸出結果。具體可參照實驗的程序模擬.各功能程序要求自行編寫程序實現,不得調用現有操作系統提供的模塊或功能函數。磁盤調度程序模擬。先來先服務調度算法.最短尋道時間優先調度,循環(SCAN)調度算法。程序設計語言自選,最終以軟件(含源代碼以及執行程序)和設計報告的形式提交課程設計結果.。磁盤調度讓有限的資源發揮更大的作用。在多道程序設計的計算機系統中,各個進程可能會不斷提出不同的對磁盤進行讀/寫操作的請求。由于有時候這些進程的發送請求的速度比磁盤響應的還要快,因此我們有必要為每個磁盤設備建立一個等待隊列。概要設計 1.先來先服務(FCFS)的設計思想 即先來的請求先被響應。FCFS策略看起來似乎是相當“公平”的,但是當請求的頻率過高的時候FCFS策略的響應時間就會大大延長。FCFS策略為我們建立起一個隨機訪問機制的模型,但是假如用這個策略反復響應從里到外的請求,那么將會消耗大量的時間。為了盡量降低尋道時間,看來我們需要對等待著的請求進行適當的排序,而不是簡單的使用FCFS策略。這個過程就叫做磁盤調度管理。有時候fcfs也被看作是最簡單的磁盤調度算法。 2.最短尋道時間優先調度(SSTF)的設計思想 最短時間優先算法選擇這樣的進程。要求訪問的磁道,與當前磁頭所在的磁道距離最近,以使每次的尋道時間最短。 3.掃描算法(SCAN)的設計思想 掃描(SCAN)調度算法:該算法不僅考慮到欲訪問 的磁道與當前磁道間的距離,更優先考慮的是磁頭當前的移動方向。例如,當磁頭正在自里向外移動時,SCAN算法所考慮的下一個訪問對象,應是其欲訪問的磁道,既在當前磁道之外,又是距離最近的。這樣自里向外的訪問,直至再無更外的磁道需要訪問時,才將磁道換向自外向里移動。這時,同樣也是每次選擇這樣的進程來調度,也就是要訪問的當前位置內距離最近者,這樣,磁頭又逐步地從外向里移動,直至再無更里面的磁道要訪問,從而避免了出現“饑餓”現像。 4.循環掃描(CSACN)的設計思想 循環掃描(CSCAN)算法:當磁頭剛從里向外移動而越過了某一磁道時,恰好又有一進程請求訪問此磁道,這時,該里程就必須等待,為了減少這種延遲,CSCAN算法規定磁頭單向移動,而本實驗過程中我們所設計的是磁頭從里向外移動,而從外向里移動時只須改方向而已,本實驗未實現。但本實驗已完全能演示循環掃描的全過程。 沈陽理工大學 沈陽理工大學課程設計專用紙 No3 5 代碼及流程 1.先來先服務(FCFS) 圖 1—1 FCFS的流程圖 沈陽理工大學 沈陽理工大學課程設計專用紙 No4 2.最短尋道時間優先調度(SSTF) 圖1—2 SSTF的流程圖 沈陽理工大學 沈陽理工大學課程設計專用紙 No5 3.掃描算法(SCAN) 圖1—3 SCAN的流程圖 沈陽理工大學 沈陽理工大學課程設計專用紙 No6 4.循環掃描(CSCAN) 圖1—4 CSCAN的流程圖 沈陽理工大學 沈陽理工大學課程設計專用紙 No7 圖1—5 主函數的流程圖 沈陽理工大學 沈陽理工大學課程設計專用紙 No8 源代碼: #include“stdio.h” #include“stdlib.h” //#include“iostream.h” #define maxsize 100 //定義最大數組域 //先來先服務調度算法 void FCFS(int array[],int m){ int sum=0,j,i;int avg;printf(“n FCFS調度結果: ”);for(i=0;i } avg=sum/(m-1);//計算平均尋道長度 printf(“n 移動的總道數: %d n”,sum);printf(“平均尋道長度: %d n”,avg);} //最短尋道時間優先調度算法 void SSTF(int array[],int m){ int temp;int k=1;int now,l,r;int i,j,sum=0;int avg;for(i=0;i 沈陽理工大學 沈陽理工大學課程設計專用紙 No9 array[i]=array[j];array[j]=temp;} } } for(i=0;i for(i=m-1;i>=0;i--)//將數組磁道號從大到小輸出 printf(“%d ”,array[i]);sum=now-array[0];//計算移動距離 } else if(array[0]>=now)//判斷整個數組里的數是否都大于當前磁道號 { for(i=0;i printf(“%d ”,array[l]);sum+=now-array[l];//計算移動距離 now=array[l];l=l-1;} else 沈陽理工大學 沈陽理工大學課程設計專用紙 No10 { printf(“%d ”,array[r]);sum+=array[r]-now;//計算移動距離 now=array[r];r=r+1;} } if(l=-1){ for(j=r;j printf(“%d ”,array[j]);} sum+=array[m-1]-array[0];//計算移動距離 } else { for(j=l;j>=0;j--){ printf(“%d ”,array[j]);} sum+=array[m-1]-array[0];//計算移動距離 } } avg=sum/m;printf(“n 移動的總道數: %d n”,sum);printf(“平均尋道長度: %d n”,avg);} //掃描算法 void SCAN(int array[],int m)//先要給出當前磁道號和移動臂的移動方向 { int temp;int k=1;int now,l,r,d;int i,j,sum=0;int avg;for(i=0;i 沈陽理工大學 沈陽理工大學課程設計專用紙 No11 { temp=array[i];array[i]=array[j];array[j]=temp;} } } for(i=0;i printf(“n SCAN調度結果: ”);for(i=m-1;i>=0;i--){ printf(“%d ”,array[i]);//將數組磁道號從大到小輸出 } sum=now-array[0];//計算移動距離 } else if(array[0]>=now)//判斷整個數組里的數是否都大于當前磁道號 { printf(“n SCAN調度結果: ”);for(i=0;i 沈陽理工大學 沈陽理工大學課程設計專用紙 No12 { for(j=l;j>=0;j--){ printf(“%d ”,array[j]);} for(j=r;j //循環掃描算法 void CSCAN(int array[],int m){ int temp;int k=1;int now,l,r,d;int i,j,sum=0;int avg;for(i=0;i 沈陽理工大學 沈陽理工大學課程設計專用紙 No13 { temp=array[i];array[i]=array[j];array[j]=temp;} } } for(i=0;i printf(“n CSCAN調度結果: ”);for(i=0;i printf(“%d ”,array[i]);//將磁道號從小到大輸出 } sum=now-array[0]+array[m-1];//計算移動距離 } else if(array[0]>=now)//判斷整個數組里的數是否都大于當前磁道號 { printf(“n CSCAN調度結果: ”);for(i=0;i printf(“%d ”,array[i]);//將磁道號從小到大輸出 } sum=array[m-1]-now;//計算移動距離 } else { while(array[k] 沈陽理工大學 沈陽理工大學課程設計專用紙 No14 { for(j=l;j>=0;j--){ printf(“%d ”,array[j]);} for(j=m-1;j>=r;j--){ printf(“%d ”,array[j]);} sum=2*(array[m-1]-array[0])-array[r]+now;//計算移動距離 }//磁道號減小方向 else { for(j=r;j // 操作界面 int main(){ int c;FILE *fp;//定義指針文件 int cidao[maxsize];//定義磁道號數組 int i=0,count;fp=fopen(“cidao.txt”,“r+”);//讀取cidao.txt文件 if(fp==NULL)//判斷文件是否存在 { printf(“n 請 先 設 置 磁 道!n”);exit(0);} while(!feof(fp))//如果磁道文件存在 沈陽理工大學 沈陽理工大學課程設計專用紙 No15 { fscanf(fp,“%d”,&cidao[i]);//調入磁道號 i++;} count=i-1;printf(“n-------------------n”);printf(“ 10-11OS課程設計--磁盤調度算法系統n”);printf(“ 計算機科學與技術二班n”);printf(“ 姓名:宋思揚n”);printf(“ 學號:0803050203n”);printf(“ 電話:************n”);printf(“ 2010年12月29日n”);printf(“n-------------------n”);printf(“n 磁道讀取結果:n”);for(i=0;i 1、先來先服務算法(FCFS)n”);printf(“ 2、最短尋道時間優先算法(SSTF)n”);printf(“ 3、掃描算法(SCAN)n”);printf(“ 4、循環掃描算法(CSCAN)n”);printf(“ 5.退出n”);printf(“n”);printf(“請選擇:”);scanf(“%d”,&c);if(c>5)break;switch(c)//算法選擇 { case 1: FCFS(cidao,count);//先來先服務算法 printf(“n”);break;case 2: SSTF(cidao,count);//最短尋道時間優先算法 printf(“n”);break;case 3: 沈陽理工大學 沈陽理工大學課程設計專用紙 No16 SCAN(cidao,count);//掃描算法 printf(“n”);break;case 4: CSCAN(cidao,count);//循環掃描算法 printf(“n”);break;case 5: exit(0);} } return 0;} 6 運行結果 圖2—1 運行界面 沈陽理工大學 沈陽理工大學課程設計專用紙 No17 圖2—2 運行FCFS的界面 圖2—3 運行SSTF的界面 圖2—4 運行SCAN的界面 沈陽理工大學 沈陽理工大學課程設計專用紙 No18 圖2—5 運行SCAN的界面 圖2—6 運行CSCAN的界面 圖2—7 運行CSCAN的界面 沈陽理工大學 沈陽理工大學課程設計專用紙 No19 運行結果: 四種磁盤調度運行結果正確,與預期的相符。設計心得 此次操作系統的課程設計,從理論到實踐,在兩個星期的日子里,可以說是苦多于甜,但是可以學到很多很多的的東西,同時不僅可以鞏固了以前所學過的知識,而且學到了很多在書本上所沒有學到過的知識。通過這次課程設計使我懂得了理論與實際相結合是很重要的,只有理論知識是遠遠不夠的,只有把所學的理論知識與實踐相結合起來,從理論中得出結論,才能真正為社會服務,從而提高自己的實際動手能力和獨立思考的能力。 本次實驗首先要了解磁盤調度的工作原理及四種調度方法的工作原理。在課程設計前的準備工作時,先把這部分工作做完了。在設計總的程序框架的時候,要注意各功能模塊的位置,盡量做到簡潔、有序;各功能模塊與主程序要正確銜接。 在設計的過程中遇到許多問題,我設計的是四種調度算法中的后兩種。例如:在最初程序設計時主要有兩種構思:1)選用數據結構是鏈表的。2)選用數組。我最初嘗試了用鏈表,覺得方便易懂,但是在循環掃描處出現了些問題,后來又轉變了設計思路,選用了數組,直接進行排序,然后再聯系到各功能模塊。 同時在設計的過程中發現了自己的不足之處,對以前所學過的知識理解得不夠深刻,掌握得不夠牢固,自身知識的很多漏洞,看到了自己的實踐經驗還是比較缺乏,理論聯系實際的能力還急需提高。比如說編語言掌握得不好,應用程序編寫不太會……通過這次課程設計之后,一定把以前所學過的知識重新溫故。在此,也感謝在課程設計過程中幫我解惑的老師和同學。參考文獻 [1] 《操作系統》 人民郵電出版社 宗大華 宗濤 陳吉人 編著 [2] 《C語言程序設計》 清華大學出版社 馬秀麗 劉志嫵 李筠 編著 [3] 《操作系統實驗指導書》 沈陽理工大學 唐巍 菀勛 編著 沈陽理工大學 實驗報告六磁盤調度算法 班級:軟技2班學號:201467003084 姓名:劉道林 一. 實驗內容: 熟悉磁盤的結構以及磁盤的驅動調度算法的模擬,編程實現簡單常用的磁盤驅動調度算法先來先服務(FIFO)、電梯調度算法、最短尋找時間優先算法、掃描(雙向掃描)算法、單向掃描(循環掃描)算法等。編程只需實現兩個算法。 題目可 以選取教材或習題中的相關編程實例。 編程語言建議采用c/c++或Java。模擬程序鼓勵采用隨機數技術、動態空間分配技術,有條件 的最好能用圖形界面展現甚至用動畫模擬。 實驗性質:驗證型。 二. 實驗目的和要求 1)掌握使用一門語言進行磁盤驅動調度算法的模擬; 2)編寫程序將磁盤驅動調度算法的過程和結果能以 較簡明直觀的方式展現 出來。 三. 實驗原理、方法和步驟 1.實驗原理 磁盤驅動調度對磁盤的效率有重要影響。磁盤驅動調度算法的好壞直接影響輔助存儲器的效率,從而影響計算機系統的整體效率。 常用的磁盤驅動調度算法有:最簡單的磁盤驅動調度算法是先入先出(FIFO)法。這種算法的實質是,總是嚴格按時間順序對磁盤請 求予以處理。算法實現簡單、易于理解并且相對公平,不會發生進程餓死現象。但該算法可能會移動的柱面數較多并且會經常更換移 動方向,效率有待提高。 最短尋找時間優先算法:總是優先處理最靠近的請求。該算法移動的柱面距離較小,但可能會經常改變 移動方向,并且可能會發生進程饑餓現象。 電梯調度:總是將一個方向上的請求全部處理完后,才改變方向繼續處理其他請求。 掃描(雙向掃描):總是從最外向最里進行掃描,然后在從最里向最外掃描。該算法與電梯調度算法的區別是電梯調度在沒有最外或 最里的請求時不會移動到最外或最里柱面,二掃描算法總是移到最外、最里柱面。兩端的請求有優先服被務的跡象。 循環掃描(單 向掃描):從最外向最里進行柱面請求處理,到最里柱面后,直接跳到最外柱面然后繼續向里進行處理。該算法與掃描算法的區別是,回來過程不處理請求,基于這樣的事實,因為里端剛被處理。 2.實驗方法 1)使用流程圖描述演示程序的設計思想; 2)選取c/c++、Java等計算機語言,編程調試,最終給出運行正確的程序。 四. 實驗結果分析 能夠將磁盤驅動調度算法在各種情況下都能得出正確的結論。對FIFO、最短尋找時間優先或電梯調度算法能夠 在多次模擬數據下得出平均移動柱面數,并進行效率比較分析 五.源程序代碼 #include char name[32]; /*定義進程名稱*/ int team; /*定義柱面號*/ int ci; /*定義磁道面號*/ int rec; /*定義記錄號*/ struct _proc *prior; struct _proc *next;} PROC; PROC *g_head=NULL,*g_curr=NULL,*local; int record=0; int yi=1;void init(){ PROC *p; 鏈表(初始I/O表)*/ g_head =(PROC*)malloc(sizeof(PROC)); g_head->next = NULL; g_head->prior = NULL; p =(PROC*)malloc(sizeof(PROC)); strcpy(p->name, “P1”); p->team=100; p->ci=10; p->rec=1; p->next = NULL; p->prior = g_head; g_head->next = p; g_curr=g_head->next; p =(PROC*)malloc(sizeof(PROC)); strcpy(p->name, “P2”); p->team=30; p->ci=5; p->rec=5; /*初始化 p->next = NULL; p->prior = g_curr; g_curr->next = p; g_curr=p; p =(PROC*)malloc(sizeof(PROC)); strcpy(p->name, “P3”); p->team=40; p->ci=2; p->rec=4; } void PrintInit() { p->next = NULL;p->prior = g_curr;g_curr->next = p;g_curr=p;p =(PROC*)malloc(sizeof(PROC));strcpy(p->name, “P4”);p->team=85;p->ci=7;p->rec=3;p->next = NULL;p->prior = g_curr;g_curr->next = p;g_curr=p;p =(PROC*)malloc(sizeof(PROC));strcpy(p->name, “P5”);p->team=60;p->ci=8;p->rec=4;p->next = NULL;p->prior = g_curr;g_curr->next = p;g_curr=g_head->next;local =(PROC*)malloc(sizeof(PROC)); /*選中進程*/ strcpy(local->name, “P0”);local->team=0;local->ci=0;local->rec=0;local->next=NULL;local->prior=NULL; /*打印I/O表*/ PROC *t = g_head->next;printf(“------n”);printf(“ ---------I/O LIST---------n”);printf(“ process team ci rec n”);while(t!=NULL) { printf(“%4s %8d %8d %5dn”, t->name, t->team, t->ci, t->rec); t = t->next; } printf(“nnCurrent process is :n”); printf(“------------------------------nn”); printf(“ process team ci rec n”); printf(“%4s %8d %8d %5dn”, local->name, local->team, local->ci, local->rec); switch(yi) { case 1: { printf(“current direction is UPn”); break; } case 0: { printf(“current direction is downn”); break; } } } void acceptreq() /*接受請求函數*/ { PROC *p; p =(PROC*)malloc(sizeof(PROC)); printf(“please input the information of the new processnprocess-name:nprocess-teamnprocess-cinprocess-recn”); printf(“1.namen”); scanf(“%s”,p->name); printf(“2.team 0-199n”); scanf(“%d”,&p->team); /*輸入請求進程信息*/ printf(“3.ci 0-19n”); scanf(“%d”,&p->ci); printf(“4.rec 0-7n”); scanf(“%d”,&p->rec); getchar(); g_curr=g_head; /*將此節點鏈入I/O請求表*/ while(g_curr->next!=NULL)g_curr=g_curr->next; p->next=NULL; p->prior=g_curr; g_curr->next=p; g_curr=g_head->next; printf(“NEW I/O LISTnn”); PrintInit(); /*將新的I/O請求表輸出*/ } void qddd() /*驅動調度函數*/ { PROC *out; int min; int max=g_head->next->team; if(g_head->next==NULL); /*若已全部調度,則空操作*/ else { switch(yi) { case 1: { min=g_head->next->team; out=g_head->next; /*選出最小的team進程,模擬啟動此進程*/ strcpy(local->name,out->name); local->team=out->team; local->ci=out->ci; local->rec=out->rec; for(g_curr=g_head->next;g_curr!=NULL;g_curr=g_curr->next) { if(g_curr->team > record) { min = g_curr->team; break; } } for(g_curr=g_head->next;g_curr!=NULL;g_curr=g_curr->next) { if(min>=g_curr->team&&g_curr->team>record) { min=g_curr->team;out=g_curr; strcpy(local->name,out->name); local->team=out->team;local->ci=out->ci;local->rec=out->rec; } } printf(“n-----------------------n”); printf(“the process choosed :n”); printf(“ process team ci rec n”); printf(“%4s %8d %8d %5dn”, out->name, out->team, out->ci,out->rec); (g_curr=g_head->next;g_curr!=NULL;g_curr=g_curr->next) (max if(max==record) yi=0; record=1000; break; break; }/*case 1*/ case /*case 1 的對稱過程*/ { max=g_head->next->team; strcpy(local->name,out->name); local->team=out->team; record = local->team;printf(“%d”,record);for { if } { } 0: out=g_head->next; local->ci=out->ci; local->rec=out->rec; for(g_curr=g_head->next;g_curr!=NULL;g_curr=g_curr->next) { if(g_curr->team < record) { max = g_curr->team; break; } (g_curr=g_head->next;g_curr!=NULL;g_curr=g_curr->next) { if(max<=g_curr->team&&g_curr->team { max=g_curr->team;out=g_curr; strcpy(local->name,out->name); local->team=out->team; local->ci=out->ci;local->rec=out->rec; } } printf(“n-----------------------n”); printf(“the process choosed :n”); printf(“ process team ci rec n”); printf(“%4s %8d %8d %5dn”, out->name, out->team, out->ci,out->rec); } for min=g_head->next->team; for(g_curr=g_head->next;g_curr!=NULL;g_curr=g_curr->next) { if(min>g_curr->team)min=g_curr->team; } record = local->team; if(min==record) { yi=1;record=0; break; } break; } default : return-1; }/*switch*/ if(out->next==NULL) /*將選中的進程從I/O請求表中刪除*/ { out->prior->next=NULL;free(out); } else { out->prior->next=out->next; out->next->prior=out->prior; free(out); } }/*else*/ } void acceptnum() /*通過輸入0~1選擇‘驅動調度’或是‘接受請求’*/ { float num; char c; while(1) { printf(“---------------n”); printf(“please input a number between 0 and 1nnum<=0.5:accept requestnnum>0.5:qudong diaodunnnum==2:I/O LISTnnnum=?n”); scanf(“%f”,&num); getchar(); while((num<0||num>1)&&num!=2) /*過濾不合法數據 注意:本程序其他輸入數據可能未過濾*/ { printf(“number ERROR!Input again please!nnum=?n ”); scanf(“%f”,&num); getchar(); } if(num>0.5&&num!=2) /*驅動調度*/ { if(g_head->next==NULL) { printf(“nn”); printf(“---------------------n”); printf(“I/O list is empty!!n”); /*請求表為空 無需調度*/ } else { printf(“qudong diaodun”); qddd(); /*調用函數進行調度*/ } } else if(num<=0.5) /*接受請求*/ { printf(“accept requestnn”); acceptreq(); } else if(num==2) /*通過輸入2顯示當前請求I/O表*/ { printf(“I/O LIST;”); printf(“-------------------n”); PrintInit(); printf(“n”); printf(“-----------------------n”); printf(“choose 'n' to quit else to continuen”); if(strcmp(c=getchar(),'n')==0||strcmp(c=getchar(),'N')==0) clrscr(); printf(“nnnnnn”); printf(“thank you for testing my program!n”); printf(“ ---by 01n”); sleep(2); printf(“nnBYEbye!”); sleep(2); return-1; else { clrscr(); } /*輸入n離開本程序*/ { } } } } main() /*主程序*/ { init(); PrintInit(); acceptnum();}第三篇:操作系統課程設計-磁盤調度算法
第四篇:操作系統課程設計,磁盤調度算法范文
第五篇:實驗報告六 磁盤調度算法