第一篇:模擬磁盤調度算法系統的設計畢業設計
目錄
一、設計任務及主要技術....................................................................3
二、設計方案及論證結果....................................................................4
三、系統的原理框圖..................................................................................5
四、設計程序....................................................................................................12
五、實驗結果....................................................................................................20
六、調試分析及故障處理..................................................................24
七、設計結論....................................................................................................25
八、心得體會....................................................................................................26
一、設計任務及主要技術
1.整體功能概述(設計任務):
磁盤是外設中一個很常用的部分,所以,對磁盤數據的尋道時間的長短可以直接影響機器的整體運行速度的快慢。本設計為一個模擬磁盤調度算法的磁盤調度模擬系統,能夠模擬先來先服務(FCFS)算法、最短尋道時間(SSTF)算法、電梯(SCAN)算法、環形掃描(C_SCAN)算法及N_SCAN算法五個磁盤調度算法,輸入為一組作業的磁道請求,輸出為按選擇的算法執行時的磁頭移動軌跡。其中,先來先服務(FCFS)算法、最短尋道時間(SSTF)算法、電梯(SCAN)算法為基本算法,環形掃描(C_SCAN)算法及N_SCAN算法為擴展算法。
2.運行環境:
(1)硬件環境
Intel core i5 CPU
(2)軟件環境
Windows 7
Microsoft Visual C++ 6.0
3.主要技術:
(1)用C語言編寫程序;
(2)對編程軟件Microsoft Visual C++ 6.0的了解和使用;
(3)操作系統基礎知識(主要是對先來先服務(FCFS)算法、最短尋道時間(SSTF)算法、電梯(SCAN)算法的了解);
(4)操作系統擴展知識(通過網絡自學環形掃描(C_SCAN)算法及N_SCAN算法)。
二、設計方案及論證結果
1.設計方案:
(1)先來先服務算法(First-Come,First-Served,FCFS)
此算法為一種最簡單的磁盤調度算法。它直接根據作業請求磁盤的先后順序對磁盤進行尋訪。此算法公平、簡單,每個作業的磁盤請求都可以得到處理,不會出現某個作業的請求長期得不到滿足的情況。但此算法未對尋道方案進行優化,故平均周轉時間及帶權周轉時間都會較長。
(2)最短尋道時間優先算法(Shortest Seek Time First,SSTF)
此算法優先選擇距離當前磁頭位置最近的作業磁道請求。此算法可以使得每次尋道時所用的時間都最短,但不能保證平均周轉時間及帶權周轉時間最短。
(3)電梯算法(SCAN)
此算法同時考慮下一個作業磁道請求與當前磁頭位置的距離和當前磁頭移動方向。本設計默認磁頭當前移動方向為自內向外,故SCAN算法先選擇當前磁頭之外距離其最近的磁道進行訪問,直到再無更外的磁道請求,再將磁臂換向,訪問磁頭內側距離當前磁頭位置最近的作業磁道請求。此算法避免了饑餓現象的出現,每個作業的磁盤請求都可以得到處理,且使每次尋道時間相對較短。
(4)環形掃描算法(C_SCAN)
此算法磁頭移動方向一直為自內向外,同時考慮下一個作業磁道請求與當前磁頭位置的距離最短。先選擇當前磁頭之外距離其最近的磁道進行訪問,直到再無更外的磁道請求,再直接將磁頭移到最內側磁道(此過程快速移動,并不訪問任何磁道),再由內向外順次訪問距離當前磁頭位置最近的作業磁道請求。此算法每個作業的磁盤請求都可以得到處理,且使每次尋道時間相對較短。由于該方法一直保持磁頭移動尋訪方向不變,對兩端磁道請求比較有利。
(5)N_SCAN算法
此算法同時考慮下一個作業磁道請求與當前磁頭位置的距離和當前磁頭移動方向,但每次磁臂調轉方向時,將同時處理在磁頭向一側移動過程當中輸入的作業請求。本設計默認磁頭當前移動方向為自內向外,先選擇當前磁頭之外距離其最近的磁道進行訪問,直到再無更外的磁道請求,接下來一并考慮在磁頭向外側移動過程當中輸入的作業請求與磁頭內側未被處理的作業磁道請求。此算法對中間磁道請求比較有利。
2.論證結果:
本設計輸入當前磁頭位置及一組作業磁道請求。選擇所需的算法,輸出相應結果:(1)先來先服務算法(FCFS)
按輸入順序輸出訪問序列。
(2)最短尋道時間優先算法(SSTF)
依次輸出距離當前磁頭位置最近的磁道請求。
(3)電梯算法(SCAN)
先按照從小到大的順序輸出所輸入的當前磁頭位置外側的磁道請求,再按照從大到小的順序輸出所輸入的當前磁頭位置內側的磁道請求。
(4)環形掃描算法(C_SCAN)
先按照從小到大的順序輸出所輸入的當前磁頭位置外側的磁道請求,再按照從小到大的順序輸出所輸入的當前磁頭位置內側的磁道請求。
(5)N_SCAN算法
先按照從小到大的順序輸出所輸入的當前磁頭位置外側的磁道請求,再按照從大到小的順序輸出在磁頭向外側移動過程當中輸入的作業請求與所輸入的當前磁頭位置內側的磁道請求。
三、系統的原理框圖
1.總體框圖:
本系統劃分為五個模塊:先來先服務算法模塊FCFS(int track[])、最短尋道時間算法模塊SSTF(int correnttrack,int track[])、電梯算法模塊SCAN(int correnttrack,int track[])、環形掃描算法模塊C_SCAN(int correnttrack,int track[])及N_SCAN算法模塊N_SCAN(int correnttrack,int track[])。
總體框圖:
磁盤調度模擬系統先來先服務算法最短尋道時間優先算法電梯算法環形掃描算法N_SCAN算法 圖1 總體框圖 2.模塊框圖:
(1)先來先服務算法模塊void FCFS(int track[])直接根據作業請求磁盤的先后順序對磁盤進行尋訪。此算法公平、簡單,每個作業的磁盤請求都可以得到處理,不會出現某個作業的請求長期得不到滿足的情況。
先來先服務算法流程圖:
FCFS輸入當前磁頭位置 輸入一組作業磁道請求i=1i<10是輸出track[i]否i=i+1結束
圖2 先來先服務算法模塊流程圖
(2)最短尋道時間優先算法模塊void SSTF(int correnttrack,int track[])優先選擇距離當前磁頭位置最近的作業磁道請求,可以使得每次尋道時所用的時間都最短。
最短尋道時間優先算法流程圖:
SSTF輸入當前磁頭位置及 一組作業磁道請求Min=|corrent-track[0]|i=0i<10是j=0j<10是track[j]!=-1d=|corrent-track[j]j++d 圖3最短尋道時間優先算法模塊流程圖 (3)電梯算法模塊void SCAN(int correnttrack,int track[])默認磁頭當前移動方向為自內向外,先選擇當前磁頭之外距離其最近的磁道進行訪問,6 直到再無更外的磁道請求,再將磁臂換向,訪問磁頭內側距離當前磁頭位置最近的作業磁道請求。 電梯算法流程圖: C_SCANk=0;min=track[0]i=0i<10是j=0j<10是i++j++Track[j]!=-1&&track[j] 圖4 電梯算法模塊流程圖 (4)環形掃描算法模塊void C_SCAN(int correnttrack,int track[])先選擇當前磁頭之外距離其最近的磁道進行訪問,直到再無更外的磁道請求,再直接將 7 磁頭移到最內側磁道(此過程快速移動,并不訪問任何磁道),再由內向外順次訪問距離當前磁頭位置最近的作業磁道請求。一直保持磁頭移動尋訪方向不變,對兩端磁道請求比較有利。 環形掃描算法流程圖: C_SCANk=0;min=track[0]i=0i<10是j=0j<10是i++j++Track[j]!=-1&&track[j] 圖5 環形掃描算法模塊流程圖 (5)N_SCAN算法模塊void N_SCAN(int correnttrack,int track[])本設計默認磁頭當前移動方向為自內向外,先選擇當前磁頭之外距離其最近的磁道進行訪問,直到再無更外的磁道請求,接下來一并考慮在磁頭向外側移動過程當中輸入的作業請求與磁頭內側未被處理的作業磁道請求。此算法對中間磁道請求比較有利。 N_SCAN算法流程圖: N_SCANk=0;min=track[0]i=0i<10是j=0j<10是i++j++Track[j]!=-1&&track[j] 1j=k-1;i=10-k;i<10i++是Line[i]=dLine[j]j=j-1;否k=9-k;是否還有作業請求是輸入作業請求k=k-1;否K=9;max=Line[9];i=0;lLine[.]=-1i<10是j=0j<10是i++j++Line[j]>maxmax=Line[j];k=j否否lLine[i]=Line[k];Line[k]=-1;max=0;Print(lLine);結束 圖7 N_SCAN算法模塊流程圖(2) 四、設計程序 1.主要模塊代碼: (1)先來先服務算法void FCFS(int track[])直接根據作業請求磁盤的先后順序對磁盤進行尋訪。先來先服務算法代碼: void FCFS(int track[]){ int k;for(k=0;k<9;k++){ printf(“%d->”,track[k]); } printf(“%d”,track[9]);} (2)最短尋道時間優先算法void SSTF(int correnttrack,int track[])優先選擇距離當前磁頭位置最近的作業磁道請求。最短尋道時間優先算法代碼: void SSTF(int correnttrack,int track[]){ int Line[10];int i;int j;int d;int min_d;int k;int corrent; min_d=abs(correnttrack-track[0]); k=0;corrent=correnttrack; for(i=0;i<10;i++){ for(j=0;j<10;j++) { if(track[j]!=-1) { d=abs(corrent-track[j]); if(d { min_d=d; k=j; } } } Line[i]=track[k]; corrent=Line[i]; track[k]=-1; min_d=65536; } printf(“%d->”,correnttrack);Print(Line);} (3)電梯算法void SCAN(int correnttrack,int track[])默認磁頭當前移動方向為自內向外,先選擇當前磁頭之外距離其最近的磁道進行訪問,直到再無更外的磁道請求,再將磁臂換向,訪問磁頭內側距離當前磁頭位置最近的作業磁道請求。 電梯算法代碼: void SCAN(int correnttrack,int track[]){ int Line[10];int dLine[10];int i;int j;int k; int min; k=0; min=track[0];for(i=0;i<10;i++){ for(j=0;j<10;j++) { if(track[j]!=-1) { if(track[j] { min=track[j]; k=j; } } } dLine[i]=track[k]; track[k]=-1; min=65536;} k=0;for(i=0;i<10;i++){ if(correnttrack>dLine[i]) { k=k+1; } } j=k;for(i=0;i<10-k;i++){ Line[i]=dLine[j]; j=j+1; } j=k-1;for(i=10-k;i<10;i++){ Line[i]=dLine[j]; j=j-1; } Print(Line);}(4)環形掃描算法void C_SCAN(int correnttrack,int track[])先選擇當前磁頭之外距離其最近的磁道進行訪問,直到再無更外的磁道請求,再直接將磁頭移到最內側磁道(此過程快速移動,并不訪問任何磁道),再由內向外順次訪問距離當前磁頭位置最近的作業磁道請求。 環形掃描算法代碼: void C_SCAN(int correnttrack,int track[]){ int Line[10];int dLine[10];int i;int j;int k;int min;k=0;min=track[0];for(i=0;i<10;i++){ for(j=0;j<10;j++) { if(track[j]!=-1) { if(track[j] { min=track[j]; k=j; } } } dLine[i]=track[k]; track[k]=-1; min=65536;} k=0;for(i=0;i<10;i++){ if(correnttrack>dLine[i]) { k=k+1; } } j=k;for(i=0;i<10-k;i++){ Line[i]=dLine[j]; j=j+1; } j=0;for(i=10-k;i<10;i++){ Line[i]=dLine[j]; j=j+1; } Print(Line);} (5)N_SCAN算法void N_SCAN(int correnttrack,int track[])默認磁頭當前移動方向為自內向外,先選擇當前磁頭之外距離其最近的磁道進行訪問,直到再無更外的磁道請求,接下來一并考慮在磁頭向外側移動過程當中輸入的作業請求與磁頭內側未被處理的作業磁道請求。 N_SCAN算法 void N_SCAN(int correnttrack,int track[]){ int Line[10];int dLine[10];int lLine[10];int i;int j;int k; int min,max;int choice; for(k=0;k<10;k++){ lLine[k]=-1; } k=0;min=track[0];for(i=0;i<10;i++){ for(j=0;j<10;j++){ if(track[j]!=-1) { if(track[j] { min=track[j]; k=j; } } } dLine[i]=track[k];track[k]=-1;min=65536;} k=0;for(i=0;i<10;i++){ if(correnttrack>dLine[i]){ k=k+1;} } j=k;for(i=0;i<10-k;i++){ Line[i]=dLine[j];printf(“%d->”,Line[i]);Line[i]=-1;j=j+1;} j=k-1;for(i=10-k;i<10;i++){ Line[i]=dLine[j];j=j-1;} printf(“n是否還有作業請求(1-是;0-否):n”);scanf(“%d”,&choice); k=9-k;while(choice==1){ printf(“n請輸入作業的磁道請求:n”); scanf(“%d”,&Line[k]); k=k-1; printf(“n是否還有作業請求(1-是;0-否):n”); scanf(“%d”,&choice); } printf(“n磁頭繼續移動軌跡為:n”); k=9; max=Line[9];for(i=0;i<10;i++){ for(j=0;j<10;j++) { if(Line[j]>max) { max=Line[j]; k=j; } } lLine[i]=Line[k]; Line[k]=-1; max=0;} for(i=0;i<9;i++){ if(lLine[i]!=-1) { printf(“%d->”,lLine[i]); } } printf(“%d”,lLine[9]);} 2.總模塊代碼: void main(){ int track[10];int n;int correnttrack;int choice=1;printf(“n******磁盤調度模擬系統******”);while(choice==1){ printf(“n請輸入當前磁道號:”); scanf(“%d”,&correnttrack); printf(“n請輸入一組作業的磁道請求<以回車分隔>:n”); scanf(“%d %d %d %d %d %d %d %d %d %d”,&track[0],&track[1],&track[2],&track[3],&track[4],&track[5],&track[6],&track[7],&track[8],&track[9]); printf(“n請選擇算法:n”); printf(“t1.先來先服務算法(FCFS)n”); printf(“t2.最短尋道時間優先算法(SSTF)n”); printf(“t3.電梯算法(SCAN)n”); printf(“t4.環形掃描算法(C_SCAN)n”); printf(“t5.(N_SCAN)n”); scanf(“%d”,&n); printf(“nn”); switch(n) { case 1: printf(“********先來先服務算法(FCFS)*********n磁頭移動軌跡為:n”); FCFS(track); break; case 2: printf(“*****最短尋道時間優先算法(SSTF)******n磁頭移動軌跡為:n”); SSTF(correnttrack,track); break; case 3: printf(“************電梯算法(SCAN)***********n磁頭移動軌跡為:n”); SCAN(correnttrack,track); break; case 4: printf(“*********環形掃描算法(C_SCAN)********n磁頭移動軌跡為:n”); C_SCAN(correnttrack,track); break; case 5: printf(“****************N_SCAN***************n磁頭移動軌跡為:n”); N_SCAN(correnttrack,track); break; } } printf(“n請問是否繼續?(1-繼續;0-退出)n”); scanf(“%d”,&choice);} 五、實驗結果 1.總模塊實驗結果: 程序開始運行,將出現輸入選擇界面; 圖8 主界面 2.基礎模塊實驗結果: (1)先來先服務算法(First-Come,First-Served,FCFS) 按輸入順序輸出訪問序列。 選擇該算法后,將輸出相應磁頭移動軌跡: 圖9 先來先服務算法0 輸出結果為69-> 23-> 120-> 45-> 77-> 31-> 55-> 99-> 150-> 2 滿足要求。 (2)最短尋道時間優先算法(Shortest Seek Time First,SSTF) 依次輸出距離當前磁頭位置最近的磁道請求。選擇該算法后,將輸出相應磁頭移動軌跡: 圖10 最短尋道優先算法 輸出結果為45-> 55-> 69-> 77-> 99-> 120-> 150-> 31-> 23-> 2 滿足要求。(3)電梯算法(SCAN) 先按照從小到大的順序輸出所輸入的當前磁頭位置外側的磁道請求,再按照從大到小的順序輸出所輸入的當前磁頭位置內側的磁道請求。 選擇該算法后,將輸出相應磁頭移動軌跡: 圖11 電梯算法 輸出結果為55-> 69-> 77-> 99-> 120-> 150-> 45-> 31-> 23-> 2 滿足要求。 3.擴展模塊實驗結果: (1)環形掃描算法(C_SCAN) 先按照從小到大的順序輸出所輸入的當前磁頭位置外側的磁道請求,再按照從小到大的順序輸出所輸入的當前磁頭位置內側的磁道請求。 選擇該算法后,將輸出相應磁頭移動軌跡: 圖12 環形掃描算法 輸出結果為55-> 69-> 77-> 99-> 120-> 150-> 2-> 23-> 31-> 45 滿足要求。 (2)N_SCAN算法 先按照從小到大的順序輸出所輸入的當前磁頭位置外側的磁道請求,再按照從大到小的順序輸出在磁頭向外側移動過程當中輸入的作業請求與所輸入的當前磁頭位置內側的磁道請求。 選擇該算法后,將輸出相應磁頭移動軌跡: 圖13 N_SCAN算法 輸出結果為55-> 69-> 77-> 99-> 120-> 150-> 88-> 45-> 31-> 23-> 8-> 2-> 1 滿足要求。 六、調試分析及故障處理 1.調試分析: (1)在代碼中錯誤的使用了中文括號“)”,導致程序出錯。 圖14 錯誤報告(2)在定義函數時誤在結尾處加分號“;”,導致調試過程中出錯。 圖15 錯誤報告 (3)由于未對變量初始化,導致錯誤: 圖16 錯誤警告 未對k初始化,如下圖: 圖17 變量表 2.故障處理: 重新檢查代碼,發現錯誤,并及時修正。調試后無誤: 圖18 無錯誤及警告 發生故障時,可采取單步調試的方法,逐條語句檢查,修正錯誤。 圖19 故障處理過程 七、設計結論 磁盤,是一種很重要也很常用的外設,其分配也有一定的分配策略。在操作系統中,作業對磁盤的請求常常要排隊,由此需要一些高效率的磁盤分配策略算法。本系統設計了五種尋道策略,其中先來先服務算法為一種最簡單的磁盤調度算法,它直接根據作業請求磁盤的先后順序對磁盤進行尋訪,公平、簡單,每個作業的磁盤請求都可以得到處理,不會出現某個作業的請求長期得不到滿足的情況,但未對尋道方案進行優化,故平均周轉時間及帶權周轉時間都會較長;最短尋道時間優先算法優先選擇距離當前磁頭位置最近的作業磁道請求,可以使得每次尋道時所用的時間都最短,但不能保證平均周轉時間及帶權周轉時間最短;電 梯算法同時考慮下一個作業磁道請求與當前磁頭位置的距離和當前磁頭移動方向先選擇當前磁頭之外距離其最近的磁道進行訪問,直到再無更外的磁道請求,再將磁臂換向,訪問磁頭內側距離當前磁頭位置最近的作業磁道請求,避免了饑餓現象的出現,每個作業的磁盤請求都可以得到處理,且使每次尋道時間相對較短;環形掃描算法的磁頭移動方向一直為自內向外,同時考慮下一個作業磁道請求與當前磁頭位置的距離最短,先選擇當前磁頭之外距離其最近的磁道進行訪問,直到再無更外的磁道請求,再直接將磁頭移到最內側磁道(此過程快速移動,并不訪問任何磁道),再由內向外順次訪問距離當前磁頭位置最近的作業磁道請求,使每個作業的磁盤請求都可以得到處理,且使每次尋道時間相對較短,由于該方法一直保持磁頭移動尋訪方向不變,對兩端磁道請求比較有利; N_SCAN算法同時考慮下一個作業磁道請求與當前磁頭位置的距離和當前磁頭移動方向,但每次磁臂調轉方向時,將同時處理在磁頭向一側移動過程當中輸入的作業請求,先選擇當前磁頭之外距離其最近的磁道進行訪問,直到再無更外的磁道請求,接下來一并考慮在磁頭向外側移動過程當中輸入的作業請求與磁頭內側未被處理的作業磁道請求,此算法對中間磁道請求比較有利。總之,各種算法都有其長處,也各有不足,需要在實際應用中權衡利弊,擇優使用。 八、心得體會 本次操作系統課程設計,我不僅完成了課程要求中的任務,更在中期檢查后聽取了老師的建議,自己上網查找了其他兩種磁盤調度算法加入了程序當中,使系統更加完善和完整。在這過程中,我不僅加深了對操作系統的了解,進一步熟悉了C語言編程和Microsoft Visual C++ 6.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();} 操作系統課程設計 磁 盤 調 度 實 踐 報 告 姓名: 董宇超 班級:計算機一班 學號:0906010124 目錄: ? 實踐內容 ? 實踐目的及意義 ? 功能設計及數據結構 ? 調試運行及測設分析 ? 存在的問題及改進設想 ? 實踐體會 ? 總結 ? 參考文獻 正文: 1.實踐內容: ? 假設磁盤只有一個盤面,并且磁盤是可移動頭磁盤。? 磁盤是可供多個進程共 享的存儲設備,但一個磁盤每個時刻只能為一個進程服務。當有進程在訪問 某個磁盤時,其它想訪問該磁盤的進程必須等待,直到磁盤一次工作結束。當有多個進程提出輸入輸出請求而處于等待狀態時,可用電梯調度算法從若 干個等待訪問者中選擇一個進程,讓它訪問磁盤。為此設置“驅動調度”進 程。 ? 由于磁盤與處理器是并行工作的,所以當磁盤在為一個進程服務時,占有處理器的其它進程可以提出使用磁盤(這里我們只要求訪問磁道),即動 態申請訪問磁道,為此設置“接受請求”進程。 要求模擬電梯調度算法,對磁盤進行移臂操作,編程實現。 2.實踐目的: 磁盤是高速、大容量、旋轉型、可直接存取的存儲設備。它作為計算機 系統的輔助存儲器,擔負著繁重的輸入輸出工作,在現代計算機系統中往往 同時會有若干個要求訪問磁盤的輸入輸出要求。 系統可采用一種策略,盡可能按最佳次序執行訪問磁盤的請求。由于磁 盤訪問時間主要受尋道時間T的影響,為此需要采用合適的尋道算法,以降 低尋道時間。 本實驗要求模擬設計一個磁盤調度程序,觀察調度程序的動態運 行過程。通過實驗理解和掌握磁盤調度的職能。 3.功能設計: 由于程序簡單,沒有設計結構體,只定義了一下變量: int m=0;//記錄磁道數目 int n;//接受輸入的磁道號 int disk[1000];//保存磁道序列 int currenttrack;//當前磁道號 int t; int i=0,j=0,k=0;//循環參數 int option;//記錄尋到方向 int sum=0;//統計尋道長度 源代碼: #include int n;//接受輸入的磁道號 int disk[1000];//保存磁道序列 int currenttrack;//當前磁道號 int t;int i=0,j=0,k=0;//循環參數 int option;//記錄尋到方向 int sum=0;//統計尋道長度 printf(“請輸入當前的磁道號:”);scanf(“%d”,¤ttrack); printf(“n--------------------1.向磁道號增加的方向訪問--------------------”);printf(“n--------------------2.向磁道號減少的方向訪問--------------------”);printf(“n請選擇的當前磁頭移動方向(1/2):”);scanf(“%d”,&option); printf(“n請輸入磁道請求序列(0~999并以<-1>結束):n”);scanf(“%d”,&n);while(n!=-1){ disk[i]=n; m++;i++; scanf(“%d”,&n);} /* 冒泡排序 使磁道請求序列從小到大排序 */ for(j=0;j for(i=0;i { if(disk[i]>disk[i+1]) { t=disk[i]; disk[i]=disk[i+1]; disk[i+1]=t; } } } /* 找到當前磁道號在磁道請求序列中的排序位置 */ k=0;for(i=0;i k++;else break;} printf(“n--------------電梯算法調度后的磁盤調度序列-------------n”);/* 第一種: 當前磁道號先向外再向里讀 */ if(option==1){ for(i=k;i printf(“%5d”,disk[i]);} for(i=k-1;i>=0;i--){ printf(“%5d”,disk[i]);} sum=2*(disk[m-1]-disk[k])+disk[k]-disk[0];printf(“n尋道長度為:%5d”,sum);} /* 第二種: 當前磁道號先向里再向外讀 */ if(option==2){ for(i=k-1;i>=0;i--){ printf(“%d ”,disk[i]); sum+=disk[i];} for(i=k;i printf(“%5d”,disk[i]); sum+=disk[i];} sum=disk[m-1]-disk[k]+2*(disk[k]-disk[0]);printf(“n尋道長度為:%5d”,sum); } printf(“n”);} 4.調試運行: 運行開始后出現如下界面,舉例輸入5: 然后出現: 1.先選擇1(按按磁道號增加的方向尋道): 接著輸入磁道序列,若要結束輸入,輸入-1即可: 然后出現如下尋道結果: 2.再選擇2(按按磁道號減少的方向尋道): 接著輸入磁道序列,若要結束輸入,輸入-1即可: 然后出現如下尋道結果: 5.存在的問題: 由于初次做操作系統模擬實驗,所以程序設計中存在很多問題,例如:由于電梯算法是從當前的磁道號開始沿著預定的方向尋道,當本方向上的請求全部滿足時,再反向尋道,但是程序模擬過程中,進程不能隨著尋道的同時添加新的進程,使得電梯調度算法不能更好的體現。只能預先輸入一串請求,然后只對這一段請求尋道。 改進之處:添加更高級的算法,使得請求能在尋道的同時加進來。 還有一些簡單的已解決的問題,不一一列舉了。 6.實踐心得體會: 通過這次實踐學會了不少內容,更深的理解了磁道調度的幾種算法,而且學 會了系統的編寫程序。在編程過程中,需要 查閱各種資料,并且學習前人的 編寫方法,找出優劣,然后形成自己的思想,最終完成程序的編寫。 通過模擬磁盤調度的電梯調度算法,并比較與其他調度算法的不同,懂得了 各種算法在不同情況下的作用。選擇一個好的調度算法可以節約很多時間。 在模擬過程中出現過好多問題,有的解決了,有的還未解決,不管如何都是 一種收獲。 在最初的時候,由于程序編寫隱藏的錯誤,編譯沒有發現,卻執行不下 去,然后改正錯誤,修復漏洞,最終滿足實驗要求。 7.總結: 為期一周的操作系統實踐課結束了,編寫了電梯調度算法的磁盤調度模 擬程序。電梯調度尋道方式就像電梯運行一樣,就是沿一個方向尋道,直到 滿足這一方向的所有請求,便反向尋道。在程序中添加了尋道長度的顯示,以便將電梯調度的效率與其他磁盤調度算法比較。 8.參考文獻: 1.操作系統教程(第4版)????孫鐘秀 主編 高等教育出版社; 2.算法與數據結構-C語言描述(第2版)??張乃孝 主編 高等教育出版社; 3.網絡資源;第二篇:操作系統課程設計-磁盤調度算法
第三篇:操作系統課程設計,磁盤調度算法范文
第四篇:實驗報告六 磁盤調度算法
第五篇:磁盤調度[推薦]