第一篇:單核與多核的CPU調(diào)度算法
1.多核CPU調(diào)度算法 1.1全局隊列調(diào)度算法
操作系統(tǒng)維護(hù)一個全局的任務(wù)等待隊列,每個進(jìn)程在執(zhí)行階段可以使用全部的處理器資源。當(dāng)系統(tǒng)中有一個CPU核心空閑時,操作系統(tǒng)就從全局任務(wù)等待隊列中選取Ready進(jìn)程開始在此核心上執(zhí)行。
優(yōu)點(diǎn):CPU核心利用率較高,能保證全局資源的充分利用。
缺點(diǎn):多處理器同時查找工作時,可能會降低處理器效率。且同一進(jìn)程可能在不同內(nèi)核上執(zhí)行,造成的進(jìn)程遷移開銷較大。1.2局部隊列調(diào)度算法
操作系統(tǒng)為每個CPU內(nèi)核維護(hù)一個局部的任務(wù)等待隊列,將所有進(jìn)程分配到與處理器對應(yīng)的進(jìn)程隊列中。當(dāng)系統(tǒng)中有一個CPU內(nèi)核空閑時,便從該核心的任務(wù)等待隊列中選取恰當(dāng)?shù)娜蝿?wù)執(zhí)行。
優(yōu)點(diǎn):充分利用局部緩存,降低了進(jìn)程遷移的開銷。任務(wù)基本上無需在多個CPU核心間切換,有利于提高CPU核心局部Cache命中率。目前多數(shù)多核CPU操作系統(tǒng)采用的是基于全局隊列的任務(wù)調(diào)度算法。
缺點(diǎn):可能造成某些處理器超負(fù)荷,而某些處理器空閑,即資源分配不均衡不充分,引起全局資源的不充分利用。2.簡單單核CPU調(diào)度算法
2.1 先到先服務(wù)調(diào)度算法:FCFS(first-come,first-served)
當(dāng)一個進(jìn)程進(jìn)入到Ready隊列,其PCB就被鏈接到隊列的尾部。當(dāng)CPU空閑時,CPU被分配給位于隊列頭的進(jìn)程(即當(dāng)前Ready隊列中已等待時間最長的進(jìn)程)。接著,該運(yùn)行進(jìn)程從隊列中被刪除。
缺點(diǎn):對于一個進(jìn)程隊列,其總的周轉(zhuǎn)時間太長,且當(dāng)進(jìn)程的I/O較為密集時,效率將會變得相當(dāng)?shù)?,CPU利用率也會變得很低。
優(yōu)點(diǎn):實(shí)現(xiàn)方式簡單,適用于長程調(diào)度和處理器密集的進(jìn)程調(diào)度。常與優(yōu)先級策略結(jié)合提供一種更有效率的調(diào)度方法。
2.2 最短作業(yè)優(yōu)先調(diào)度算法:SJF(shortest-job-first)
SJF是一種非搶占式的調(diào)度算法,其實(shí)現(xiàn)原則是取Ready隊列中處理時間最短的進(jìn)程加載入CPU,進(jìn)入CPU執(zhí)行的進(jìn)程執(zhí)行完后才釋放CPU,然后加載第二個進(jìn)程進(jìn)入CPU執(zhí)行。
缺點(diǎn):忽視了作業(yè)等待時間,會出現(xiàn)starvation現(xiàn)象,且作業(yè)執(zhí)行時間無法提前知道,也很難預(yù)估。
優(yōu)點(diǎn):算法實(shí)現(xiàn)簡單,能有效地降低作業(yè)的平均等待時間,提高系統(tǒng)吞吐量,是理論上的最優(yōu)調(diào)度算法。
2.3 最短剩余時間優(yōu)先調(diào)度算法:SRTF(Shortest Remaining Time First)SRTF調(diào)度算法是搶占式的SJF調(diào)度算法,調(diào)度程序總是首先選擇預(yù)期剩余時間最短的進(jìn)程加載進(jìn)入CPU執(zhí)行。
缺點(diǎn):總是選擇預(yù)期剩余時間最短的進(jìn)程,會造成starvation現(xiàn)象。有處理時間預(yù)估,效率不足夠高。
優(yōu)點(diǎn):不偏向長進(jìn)程,沒有額外的中斷,因此開銷較低。且對于一個進(jìn)程隊列,總的周轉(zhuǎn)時間較短,執(zhí)行效率較高,對短進(jìn)程的響應(yīng)較快。2.4 優(yōu)先級調(diào)度算法
每個進(jìn)程都有一個自己的優(yōu)先級,Ready隊列采用優(yōu)先級隊列實(shí)現(xiàn),CPU每次取Ready隊列隊首的進(jìn)程。通常情況,當(dāng)兩個進(jìn)程的優(yōu)先級相同時,我們在相同優(yōu)先級的進(jìn)程之間采用FCFS調(diào)度算法。優(yōu)先級可以通過內(nèi)部或外部方式來定義。
缺點(diǎn):會出現(xiàn)starvation現(xiàn)象(也稱無窮阻塞),且不適用于分時系統(tǒng)或交互式事務(wù)處理環(huán)境。
優(yōu)點(diǎn):主要用于批處理系統(tǒng)中,也可用于某些對實(shí)時性要求不嚴(yán)的實(shí)時系統(tǒng)中??梢圆捎美匣夹g(shù),每個進(jìn)程執(zhí)行以后其優(yōu)先級降低,以此來克服starvation的缺點(diǎn)。2.5 輪轉(zhuǎn)法調(diào)度算法
輪轉(zhuǎn)法(RR)調(diào)度算法是專門為分時系統(tǒng)設(shè)計的,是一種基于時鐘的搶占策略。定義一個小時間單元,稱為時間量或時間片。時間片通常為10ms到100ms。將Ready隊列作為循環(huán)隊列處理。CPU調(diào)度程序循環(huán)就需隊列,為每個進(jìn)程分配不超過一個時間片間隔的CPU。如果上下文切換時間約為時間片的10%,那么約10%的CPU時間會浪費(fèi)在上下文切換上。
缺點(diǎn):時間片長度設(shè)計較難,當(dāng)時間片長度過大時,會退化成FCFS調(diào)度算法。調(diào)度I/O密集型進(jìn)程時效率較低。由于輪詢調(diào)度在調(diào)度過程中不考慮瞬時信道條件,因此它將導(dǎo)致較低的整體系統(tǒng)性能。
優(yōu)點(diǎn):對不同的分組業(yè)務(wù)流隊列進(jìn)行同樣的無差別的循環(huán)調(diào)度服務(wù),對于等長業(yè)務(wù)流隊列是公平的,不存在starvation現(xiàn)象。2.6 最高響應(yīng)比優(yōu)先調(diào)度算法
首先需要理解一個概念,叫作響應(yīng)比。響應(yīng)比的計算表達(dá)式為
其中R為響應(yīng)比,w為等待處理器的時間,s為預(yù)計服務(wù)的時間。當(dāng)進(jìn)程被立即調(diào)用時,R等于歸一化周轉(zhuǎn)時間。
調(diào)度算法的過程是,當(dāng)進(jìn)程完成執(zhí)行或被阻塞時,選擇R值最大的Ready進(jìn)程加載進(jìn)入CPU執(zhí)行。
缺點(diǎn):需要預(yù)估服務(wù)時間s,效率不太高。優(yōu)點(diǎn):能克服starvation現(xiàn)象。3.復(fù)雜單核CPU調(diào)度算法
3.1 多級隊列調(diào)度算法(multilevel queue-scheduling algorithm)將Ready隊列分成多個獨(dú)立的隊列,對Ready隊列和每個獨(dú)立的隊列采用不同的調(diào)度算法進(jìn)行執(zhí)行。常用的方式是,Ready隊列采用優(yōu)先級調(diào)度算法,不同隊列根據(jù)實(shí)際情況采用合適的調(diào)度算法即可。
優(yōu)點(diǎn):綜合了多種調(diào)度算法,避免了starvation現(xiàn)象,最大限度地提高了調(diào)度效率,也提高了CPU利用率。3.2 多級反饋隊列調(diào)度算法
UNIX OS采用的調(diào)度算法。其詳細(xì)過程如下: 1.進(jìn)程在進(jìn)入待調(diào)度的隊列等待時,首先進(jìn)入優(yōu)先級最高的Q1等待。
2.首先調(diào)度優(yōu)先級高的隊列中的進(jìn)程。若高優(yōu)先級中隊列中已沒有調(diào)度的進(jìn)程,則調(diào)度次優(yōu)先級隊列中的進(jìn)程。例如:Q1,Q2,Q3三個隊列,只有在Q1中沒有進(jìn)程等待時才去調(diào)度Q2,同理,只有Q1,Q2都為空時才會去調(diào)度Q3。
3.對于同一個隊列中的各個進(jìn)程,按照時間片輪轉(zhuǎn)法調(diào)度。比如Q1隊列的時間片為N,那么Q1中的作業(yè)在經(jīng)歷了N個時間片后若還沒有完成,則進(jìn)入Q2隊列等待,若Q2的時間片用完后作業(yè)還不能完成,一直進(jìn)入下一級隊列,直至完成。
4.在低優(yōu)先級的隊列中的進(jìn)程在運(yùn)行時,又有新到達(dá)的作業(yè),那么在運(yùn)行完這個時間片后,CPU馬上分配給新到達(dá)的作業(yè)(搶占式)。
優(yōu)點(diǎn):既能使高優(yōu)先級的作業(yè)得到響應(yīng)又能使短作業(yè)(進(jìn)程)迅速完成。4.多核CPU調(diào)度算法與單核CPU調(diào)度算法對比
從上面的不同CPU調(diào)度算法,我們不難發(fā)現(xiàn),單核CPU調(diào)度算法是多核CPU調(diào)度算法的基礎(chǔ),多核CPU調(diào)度算法是單核CPU調(diào)度算法的延伸和綜合使用。我以大篇幅介紹了單核CPU的調(diào)度算法,而以少量的篇幅介紹了多核CPU調(diào)度算法,其目的也在于說明此結(jié)論。
多核CPU調(diào)度算法中,無論是全局隊列調(diào)度算法還是局部隊列調(diào)度算法,其實(shí)現(xiàn)原理均可采用單核CPU調(diào)度算法中的某一個或一些綜合起來實(shí)現(xiàn)。例如局部隊列調(diào)度算法,每一個局部隊列就相當(dāng)于一個單核CPU調(diào)度隊列,可以采用合適的單核CPU調(diào)度算法去實(shí)現(xiàn)。
第二篇:操作系統(tǒng)實(shí)驗(yàn)二——cpu調(diào)度與內(nèi)存分頁
一、試驗(yàn)?zāi)康?/p>
理解操作系統(tǒng)內(nèi)存管理的原理及分頁內(nèi)存管理方案
二、試驗(yàn)要求
1、實(shí)現(xiàn)分頁內(nèi)存管理方案,假定頁和幀的大小均為4KB,物理內(nèi)存為128MB
2、輸入為進(jìn)程ID,所需內(nèi)存大小等,輸出為頁表。
3、請按要求撰寫實(shí)驗(yàn)報告,并和源程序一起打包上傳
4、實(shí)驗(yàn)平臺不限,linux和windows均可
5、與第一次實(shí)驗(yàn)的程序整合成一個程序
三、試驗(yàn)環(huán)境
Windows XP Visual C++ 6.0
四、試驗(yàn)內(nèi)容
為了與上一個實(shí)驗(yàn)結(jié)合,并且考慮到可能需要兼容以后的實(shí)驗(yàn),所以本次實(shí)驗(yàn)不但重寫了PCB,而且按照自己對操作系統(tǒng)的理解構(gòu)造出了一虛擬的I/O設(shè)備和兩套調(diào)度程序(作業(yè)調(diào)度程序和CPU調(diào)度程序)
一、首先從與內(nèi)存分配相關(guān)的作業(yè)調(diào)度函數(shù)說起,程序中為Jobs_scheduler。Job_scheduler的作用如下圖所示;
Job_scheduler從大容量存儲設(shè)備上的緩沖池中載入新生成的進(jìn)程到內(nèi)存,同時生成新的PCB到就緒隊列中。這里涉及到了兩個數(shù)據(jù)結(jié)構(gòu)class Program,class PCB。Program :
PCB:
PCB中的state包含五個狀態(tài)NEW、READY、RUN、WAITING、TERMINATED,加入到ReadyQueue中等待運(yùn)行的PCB均為READY狀態(tài)的,運(yùn)行中會被置為RUN,WAITNG狀態(tài)為等待I/O設(shè)備的進(jìn)程,如果進(jìn)程狀態(tài)為TERMINATED,將會被移出作業(yè)隊列。
Job_scheduler函數(shù)在將program裝入內(nèi)存前,會查看幀表內(nèi)空閑的幀的數(shù)目是否大于等于program所需的頁數(shù)目,如果成立才裝入,并且為PCB構(gòu)造頁表。構(gòu)造時,先按照幀表通過順序查找找到可用的幀,然后就將頁的內(nèi)容加載上去。
二、接下來是CPU調(diào)度程序,也成為短期調(diào)度程序。
CPU_scheduler所做的工作如下圖所示,其操作的隊列是就緒隊列RedayQueue
本程序采用的調(diào)度算法為分時調(diào)度,時間片大小TimeSlice取為1(當(dāng)然這個隨時都可用改動),里面執(zhí)行程序的函數(shù)Run是模擬CPU功能的,它會返回一個值,Normal表示執(zhí)行正常,若是返回了INTERRUPT 中斷;ERROR 出錯就會中斷此次運(yùn)行,并且將所指PCB從ReadyQueue中移除。
這里的Run函數(shù)其實(shí)模擬了CPU的取指令和翻譯指令的功能,本程序只有一個有實(shí)際作用的指令,'O',如果內(nèi)存中的內(nèi)容為'0'(十進(jìn)制ASCⅡ碼值),則代表需要利用I/O設(shè)備輸出該地址內(nèi)容。如上圖所示,PCB會加入到WaitingQueue中等待I/O,并判斷此時I/O設(shè)備是否開啟,如果未開啟則開啟設(shè)備。Run函數(shù)也因此返回一個interrupt值。運(yùn)行結(jié)果
在編號為1的進(jìn)程中的第一個內(nèi)存單位設(shè)置了一條I/O指令,可以看出其發(fā)生中斷后等待I/O完成才重新回到ReadyQueue中并執(zhí)行完畢。
以上結(jié)果是在內(nèi)存足夠大的情況,下面再看一組內(nèi)存不能同時滿足需求的情況
此次內(nèi)存設(shè)為11幀,編號為1的進(jìn)程需要10幀,編號為2的進(jìn)程需要1幀,我們看到,2號進(jìn)程順利載入并執(zhí)行了,但其他進(jìn)程都要等到1號進(jìn)程執(zhí)行完釋放內(nèi)存后才能載入內(nèi)存,符合預(yù)期情況。
五、心得體會
為了很好的仿真,本次試驗(yàn)盡可能地模擬了硬件的工作,如輸入輸出設(shè)備和模擬CPU的run函數(shù),基本上把教材77頁調(diào)度問題的隊列圖所示功能模擬出來了,也大體實(shí)現(xiàn)了從用戶程序到系統(tǒng)進(jìn)程再到硬件的執(zhí)行過程。
對于本次實(shí)驗(yàn)的核心內(nèi)容——內(nèi)存管理,實(shí)現(xiàn)了從磁盤到內(nèi)存額裝載過程,實(shí)現(xiàn)了頁表的創(chuàng)建,實(shí)現(xiàn)了內(nèi)存的釋放。缺陷是沒有考慮到換入換出等動態(tài)的情況,也就是說在此做了一個假設(shè):每個進(jìn)程相互獨(dú)立且對于每個單獨(dú)的進(jìn)程來說,內(nèi)存空間是足夠大的。
第二點(diǎn)缺陷是,沒有按照題目要求分配那么多的內(nèi)存空間,因?yàn)槟敲创筝斎胼敵霾缓每刂啤?/p>
在本程序中,輸入輸出與要求有出入,并沒有輸入進(jìn)程需要的時間,而是以進(jìn)程的具體內(nèi)容代替,在這里又有一個假設(shè):假設(shè)進(jìn)程在CPU中每執(zhí)行一步需要一個單位的時間,這樣進(jìn)程的大小也就等價于進(jìn)程需要的時間了(排除有I/O請求的情況),個人認(rèn)為這樣假設(shè)比人工限定執(zhí)行時間更加貼近現(xiàn)實(shí)情況。
程序的輸入非即時的,而是通過事先設(shè)定好的5個進(jìn)程加上運(yùn)行后隨機(jī)生成的若干進(jìn)程,也是為了模擬實(shí)際情況考慮。
因?yàn)槿止ぽ斎胄枰斎脒M(jìn)程的到達(dá)時間,也就是需要根據(jù)到達(dá)時間來為緩沖池中進(jìn)程排序的問題,但實(shí)際情況下到達(dá)時間是多余的,先創(chuàng)建的先加入隊列即可,所以采用了隨機(jī)生成的方式。
為了此次實(shí)驗(yàn),復(fù)習(xí)了調(diào)度和內(nèi)存管理兩章的大部分內(nèi)容,對操作系統(tǒng)對進(jìn)程調(diào)度和內(nèi)存分配管理有了更深入的認(rèn)識,但只是從概念上,沒有看到真正操作系統(tǒng)的代碼或者算法實(shí)例,所以可能很多地方的代碼與實(shí)際情況出入很大。
代碼:
#include #include
/***************
隨機(jī)數(shù),后面隨機(jī)生成進(jìn)程用的 *************/ void rand_seed(){ int seed = static_cast
int rand_int(int a, int b){ return a + rand()%(b1)
{
pc[1]++;
}
else
{
pc[0]++;
pc[1] = 0;
}
pcb.state = READY;} else if(pc[1] < PAGE-1){
pc[1]++;} else
pcb.state = TERMINATED;}
bool io_equipment = OFF;/* I/O設(shè)備(DMA)*/ DWORD WINAPI IOEquipment(LPVOID lpParamter){ io_equipment = ON;list
::iterator pw = WaitingQueue.begin();while(pw!= WaitingQueue.end()){
/* 為了體現(xiàn)I/O設(shè)備速度較慢,所以在此用了Sleep函數(shù) */
Sleep(1000);
cout << “P” << pw->number << “ I/O : ”<<(char)Memory[AddOfIO] << endl;
if(pw->state == WAITING)
pw->state = READY;
ReadyQueue.push_back(*pw);
pw = WaitingQueue.erase(pw);
if(pw!= WaitingQueue.end())
pw++;
else
pw = WaitingQueue.begin();} io_equipment = OFF;return FINISH;}
HANDLE ioEquipment;/**
模擬CPU執(zhí)行
只實(shí)現(xiàn)了部分功能,并沒有完全按照原理模擬
**/ int Run(PCB& pcb){ pcb.state = RUN;list
::iterator p = pcb.PageTable.begin();int addr[2];
addr[1] = pcb.pc[1];addr[0] = pcb.findframe(pcb.pc[0]);
switch(Memory[addr[0] * FRAME + addr[1]]){ case 'O': //如果指令觸發(fā)了輸出設(shè)備
pcb.state = WAITING;
pcr[0] = pcb.pc[0];
pcr[1] = pcb.pc[1];
IncPc(pcb, pcr);
pcb.pc[0] = pcr[0];
pcb.pc[1] = pcr[1];
AddOfIO = addr[0] * FRAME + addr[1];
WaitingQueue.push_back(pcb);
/* 如果I/O設(shè)備未開啟,則打開,否則什么都不做 */
if(io_equipment == OFF)
ioEquipment = CreateThread(NULL, 0, IOEquipment, NULL, 0, NULL);
else
;
return INTERRUPT;default :
break;}
/* 在沒有跳轉(zhuǎn)的情況下,運(yùn)行之后,pc自加 */ pcr[0] = pcb.pc[0];pcr[1] = pcb.pc[1];IncPc(pcb, pcr);pcb.pc[0] = pcr[0];pcb.pc[1] = pcr[1];
return NORMAL;}
HANDLE hMutex = CreateMutex(NULL, FALSE, “screen”);
/* 長期調(diào)度程序,將緩沖池中的進(jìn)程加載到內(nèi)存上 */ DWORD WINAPI Jobs_scheduler(LPVOID lpParamter){ list
::iterator p = BufferList.begin();while(true){
//WaitForSingleObject(hMutex, INFINITE);
if(p!= BufferList.end()&& p->page_numbers <= FraTable.free_frame)
{
ReadyQueue.push_back(PCB(*p));
p = BufferList.erase(p);
}
else if(p!= BufferList.end())
p++;
else
p = BufferList.begin();
//ReleaseMutex(hMutex);
} }
/* 利用RR算法的短期調(diào)度程序 */ DWORD WINAPI CPU_scheduler(LPVOID lpParamter){ list
::iterator p = ReadyQueue.begin();int run_time = 0;int total_time = 1;while(true){
WaitForSingleObject(hMutex, INFINITE);
if(p == ReadyQueue.end())
p = ReadyQueue.begin();
while(run_time < TimeSlice && p->state == READY)
{
p->run_time++;
run_time++;
//cout << total_time++ << endl;
cout << “p” << p->number << “ ” << “run time ” << p->run_time << endl;
if(Run(*p)== NORMAL)
/* do nothing */;
else
{
p = ReadyQueue.erase(p);
break;
}
/* 操作系統(tǒng)負(fù)責(zé)計時 */
}
run_time = 0;
if(p->state == TERMINATED)
{
Release(*p);
p = ReadyQueue.erase(p);
}
else
{
p++;
}
ReleaseMutex(hMutex);} }
int main(){ int num = 1;Program p1(num++, “O123456089”);Program p2(num++, “0”);Program p3(num++, “01”);Program p4(num++, “01”);Program p5(num++, “01234”);BufferList.push_back(p1);BufferList.push_back(p2);BufferList.push_back(p3);BufferList.push_back(p4);BufferList.push_back(p5);
HANDLE hThread1 = CreateThread(NULL, 0, Jobs_scheduler, NULL, 0, NULL);HANDLE hThread2 = CreateThread(NULL, 0, CPU_scheduler, NULL, 0, NULL);while(true)
{
if(num < 7)
BufferList.push_back(Program(num++, “156789”));}
return 0;}
第三篇:電梯優(yōu)先調(diào)度算法
電梯優(yōu)先調(diào)度算法
電梯調(diào)度算法(ms InterView)
移臂調(diào)度算法包括以下四種:
1)先來先服務(wù)算法:根據(jù)訪問者提出訪問請求的先后次序來決定執(zhí)行次序。
2)最短尋找時間優(yōu)先調(diào)度算法:從等待的訪問者中挑選尋找時間最短的那個請求執(zhí)行,而不管訪問者的先后次序。
3)電梯調(diào)度掃描算法:從移動臂當(dāng)前位置沿移動方向選擇最近的那個柱面的訪問者來執(zhí)行,若該方向上無請求訪問時,就改變移動方向再選擇。
4)單向掃描調(diào)度算法:從0柱面開始往里單向掃描,掃到哪個執(zhí)行哪個。
*/
// t1.cpp : 定義控制臺應(yīng)用程序的入口點(diǎn)。
//
#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){ //先來先服務(wù) 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){ // 最短尋找時間優(yōu)先 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){ //電梯調(diào)度算法 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){ //單向調(diào)度算法 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;} 常用進(jìn)程調(diào)度算法的分析與評價 (一)2009-10-31 22:48 進(jìn)程調(diào)度是按照某種調(diào)度算法從就緒狀態(tài)的進(jìn)程中選擇一個進(jìn)程到處理機(jī)上運(yùn)行。進(jìn)程調(diào)度的兩種方式 : (1)非搶占調(diào)度方式 在這種調(diào)度方式中,OS一旦把處理機(jī)分配給某個就緒狀態(tài)的進(jìn)程后,就讓該進(jìn)程一直執(zhí)行下去,直至該進(jìn)程完成或由于該進(jìn)程等待某事件發(fā)生而被阻塞時,才把處理機(jī)分配給其他進(jìn)程。 (2)搶占調(diào)度方式 在這種調(diào)度方式中,進(jìn)程調(diào)度程序可根據(jù)某種原則停止正在執(zhí)行的進(jìn)程,將已分配給當(dāng)前進(jìn)程的處理機(jī)收回,重新分配給另一個處于就緒狀態(tài)的進(jìn)程。 搶占進(jìn)程調(diào)度的原則: (1)時間片原則:各進(jìn)程按系統(tǒng)分配給的一個時間片運(yùn)行,當(dāng)該時間片用完或由于該進(jìn)程等待某事件發(fā)生而被阻塞時,系統(tǒng)就停止該進(jìn)程的執(zhí)行而重新進(jìn)行調(diào)度。 (2)優(yōu)先級原則:每個進(jìn)程均賦于一個調(diào)度優(yōu)先級,通常一些重要和緊急的進(jìn)程賦于較高的優(yōu)先級。當(dāng)一個新的緊迫進(jìn)程到達(dá)時,或者一個優(yōu)先級高的進(jìn)程從阻塞狀態(tài)變成就緒狀態(tài)的時,如果該進(jìn)程的優(yōu)先級比當(dāng)前進(jìn)程的優(yōu)先級高,OS就停止當(dāng)前進(jìn)程的執(zhí)行,將處理機(jī)分配給該優(yōu)先級高的進(jìn)程,使之執(zhí)行。 (3)短進(jìn)程優(yōu)先原則:當(dāng)新到達(dá)的作業(yè)對應(yīng)的進(jìn)程比正在執(zhí)行的作業(yè)對應(yīng)進(jìn)程的運(yùn)行時間明顯短時,系統(tǒng)剝奪當(dāng)前進(jìn)程的執(zhí)行,而將處理機(jī)分配給新的短進(jìn)程,使之優(yōu)先執(zhí)行。進(jìn)程調(diào)度算法評價依據(jù) 進(jìn)程調(diào)度性能的衡量方法可以分為定性和定量兩種,在定性衡量方面,首先是調(diào)度的安全性。比如,一次進(jìn)程調(diào)度是否可能引起數(shù)據(jù)結(jié)構(gòu)的破壞等。這要求對調(diào)度時機(jī)的選擇和保存CPU現(xiàn)場十分小心。另外,系統(tǒng)開銷也是衡量進(jìn)程調(diào)度的一個重要指標(biāo),由于調(diào)度程序的執(zhí)行涉及到多個進(jìn)程的上下文切換,如果調(diào)度策略過于繁瑣和復(fù)雜,將會耗去較大的系統(tǒng)開銷。這在用戶進(jìn)程調(diào)度系統(tǒng)調(diào)用較多的情況下,將會造成響應(yīng)時間大幅度增加。 進(jìn)程調(diào)度的定量評價包括CPU的利用率評價、進(jìn)程在就緒隊列中的等待時間與執(zhí)行時間之比等。實(shí)際上,由于進(jìn)程進(jìn)入就緒隊列的隨機(jī)模型很難確定,而且進(jìn)程上下文切換等也將影響進(jìn)程的執(zhí)行效率,從而對進(jìn)程調(diào)度進(jìn)行解析是很困難的,一般情況下,大多利用模擬或測試系統(tǒng)響應(yīng)時間的方法來評價進(jìn)程調(diào)度的性能。 常用進(jìn)程調(diào)度算法的分析與評價 (二)2009-11-01 20:22 四種常用進(jìn)程調(diào)度算法的分析與評價 3.1 先來先服務(wù)算法 3.1.1 算法思想 該算法思想是按照進(jìn)入就緒隊列的先后次序來分配處理機(jī)。FCFS采用非剝奪調(diào)度方式,即 一旦某個進(jìn)程占有處理機(jī),就一直運(yùn)行下去,直到該進(jìn)程完成其工作或因等待某一事件而不能繼續(xù)執(zhí)行時才釋放處理機(jī)。 3.1.2 算法實(shí)現(xiàn)原理圖 該算法實(shí)現(xiàn)原理圖如圖1所示。 說明:Ready表示就緒隊列,Pi表示新進(jìn)入隊列的進(jìn)程,F(xiàn)inish表示進(jìn)程運(yùn)行完畢退出。 3.1.3 算法分析與評價 ① 該算法原理簡單,易于實(shí)現(xiàn)。 ② 各進(jìn)程平等競爭。 ③ 由于各進(jìn)程執(zhí)行的時間不一樣,從而導(dǎo)致相對不公平現(xiàn)象的產(chǎn)生。 ④ 該算法有利于長進(jìn)程,不利于短進(jìn)程。 ⑤ 該算法很少用來作為主調(diào)度策略,常常用作輔助調(diào)度算法使用 3.2最高優(yōu)先權(quán)優(yōu)先調(diào)度算法 3.2.1 算法思想 該算法的基本思想是進(jìn)程優(yōu)先權(quán)高者優(yōu)先調(diào)度,是一種最常用的進(jìn)程調(diào)度算法。該算法的關(guān)鍵是如何確定優(yōu)先數(shù)。通常確定優(yōu)先數(shù)的方法有兩種,即靜態(tài)法和動態(tài)法。 靜態(tài)優(yōu)先權(quán)是在創(chuàng)建進(jìn)程時確定的,其運(yùn)行特征是優(yōu)先數(shù)確定之后在整個進(jìn)行運(yùn)行期間不再改變。確定靜態(tài)優(yōu)先權(quán)的依據(jù)有進(jìn)程的類型、進(jìn)程所使用的資源、進(jìn)程的估計運(yùn)行時間等因素。進(jìn)程所申請的資源越多,估計的運(yùn)行時間越長,進(jìn)程的優(yōu)先權(quán)越低。進(jìn)程類型不同,優(yōu)先權(quán)也不同,如系統(tǒng)進(jìn)程的優(yōu)先權(quán)高于用戶進(jìn)程的優(yōu)先權(quán)。 動態(tài)優(yōu)先權(quán)是指在創(chuàng)建進(jìn)程時,其運(yùn)行特征是根據(jù)系統(tǒng)資源的使用情況和進(jìn)程的當(dāng)前特點(diǎn)確定一個優(yōu)先權(quán),在進(jìn)程運(yùn)行過程中再根據(jù)情況的變化調(diào)整優(yōu)先權(quán)。動態(tài)優(yōu)先權(quán)一般根據(jù)進(jìn)程占有CPU時間的長短、進(jìn)程等待CPU時間的長短等因素確定。占有處理機(jī)的時間越長,則優(yōu)先權(quán)越低;等待時間越長,則優(yōu)先權(quán)越高。 3.3.2 算法分析與評價 ① 靜態(tài)優(yōu)先級調(diào)度算法實(shí)現(xiàn)較為簡單,但不能反映系統(tǒng)以及進(jìn)程在運(yùn)行過程中發(fā)生的各種變化。而動態(tài)優(yōu)先級法可以滿足這個方面的需要。 ② 動態(tài)優(yōu)先級調(diào)度算法的性能一般介于時間片輪轉(zhuǎn)算法和先來先服務(wù)算法之間。 常用進(jìn)程調(diào)度算法的分析與評價 (三)2009-11-01 20:23 3.3時間片輪轉(zhuǎn)調(diào)度算法 3.3.1 算法思想 該算法思想是使每個進(jìn)程在就緒隊列中的等待時間與享受服務(wù)的時間成比例。即將CPU的處理時間分成固定大小的時間片,如果在執(zhí)行的一個進(jìn)程把它分給它的時間片用完了,但任務(wù)還沒有完成,則它也只能停止下來,釋放它所占的CPU資源,然后排在相應(yīng)的就緒隊列的后面去。 3.3.2 算法實(shí)現(xiàn)原理圖 該算法實(shí)現(xiàn)原理圖如圖2所示 說明:Ready表示就緒隊列,Pi表示新進(jìn)入隊列的進(jìn)程,F(xiàn)inish表示進(jìn)程運(yùn)行完畢退出。Not Finish表示分配給某進(jìn)程的時間片已用完但任務(wù)還沒有完成,從而插入到Ready隊列尾部。 3.3.3 算法分析與評價 ① 時間片的長度選擇比較困難 時間片的長度選擇比較困難是因?yàn)闀r間片長度的選擇直接關(guān)系到系統(tǒng)開銷和進(jìn)程的響應(yīng)時間。如果時間片長度過短→導(dǎo)致調(diào)度程序剝奪處理器的次數(shù)增加→進(jìn)程的上下文切換的次數(shù)增加→系統(tǒng)的開銷也加重;如果時間片長度過長,長到能使就緒隊列中所需要執(zhí)行時間最長的進(jìn)程執(zhí)行完 畢→輪轉(zhuǎn)法就變成了FCFS算法→FCFS短處不足就顯示出來了。 又因?yàn)镃PU的整個執(zhí)行時間=各進(jìn)程執(zhí)行時間之和+系統(tǒng)開銷(各進(jìn)程切換所花費(fèi)的CPU時間之和,假定存儲開銷忽略不計)。即。因此,時間片的長短通常需要由以下因素確定:↙系統(tǒng)的響應(yīng)時間。 ↙就緒隊列中的進(jìn)程數(shù)。 ↙進(jìn)程的切換時間。 ↙ 計算機(jī)的處理能力,計算機(jī)的速度越高,時間片就可越短。 ② 時間片長度選擇的動態(tài)性 以上僅僅作了靜態(tài)分析,通常情況下,就緒隊列里地進(jìn)程個數(shù)是不斷變化的。因此,每一次的調(diào)度都需要計算新一輪的時間片長度,不能用固定的時間片長度來進(jìn)行所有進(jìn)程的輪轉(zhuǎn)執(zhí)行。③ 該算法的擴(kuò)充——多級反饋輪轉(zhuǎn)法 在上面的算法中,未對就緒隊列中的進(jìn)程加以條件分析(即進(jìn)入就緒隊列的因素),由于進(jìn)入就緒隊列的原因不一樣,要求占用處理機(jī)的緊急程度也不一樣。主要因素有:↙分給該進(jìn)程的時間片用完,但進(jìn)程還未完成。 ↙ 分給其時間片未用完,而發(fā)生了I/O等請求后由阻塞態(tài)轉(zhuǎn)變成就緒態(tài)。 ↙新的進(jìn)程進(jìn)入。 因此,根據(jù)緊急程度的不一樣,建立多個就緒隊列,同時賦予不同的的優(yōu)先級,優(yōu)先權(quán)高的就緒隊列優(yōu)先執(zhí)行,同一就緒隊列中,優(yōu)先級相同,按照先來先服務(wù)進(jìn)行調(diào)度,運(yùn)行一個給定的時間片,如果沒有執(zhí)行完成則轉(zhuǎn)入到相應(yīng)的就緒隊列中去(運(yùn)行一次,優(yōu)先級降低一個等級,等待一個時間片,則優(yōu)先級升高一個等級)。其實(shí)現(xiàn)原理圖如圖3所示。 3.4 短進(jìn)程優(yōu)先調(diào)度算法 3.4.1 算法思想 該算法的基本思想是從就緒隊列(內(nèi)存)中選擇一個估計運(yùn)行時間最短的進(jìn)程,將處理機(jī)分配給它。 3.4.2 算法分析與評價 ① 該算法能有效降低作業(yè)的平均等待時間,提高系統(tǒng)吞吐量。 ② 對長進(jìn)程不利,甚至導(dǎo)致長期得不到處理。 ③ 該算法完全未考慮進(jìn)程的緊迫程度。 ④ 進(jìn)程的長短通常由某種策略估計提供,不能做到真正的短進(jìn)程優(yōu)先。 4結(jié)語 綜述所述,本文從算法思想、算法的實(shí)現(xiàn)原理、算法的優(yōu)缺點(diǎn)等幾個方面對先來先服務(wù)算法、時間片輪轉(zhuǎn)算法、最高優(yōu)先權(quán)優(yōu)先調(diào)度算法、短進(jìn)程優(yōu)先調(diào)度算法等四種進(jìn)程調(diào)度算法進(jìn)行詳細(xì)地論述。(轉(zhuǎn)自《計算機(jī)與信息技術(shù)》) 1.實(shí)驗(yàn)題目: 磁盤調(diào)度算法。 建立相應(yīng)的數(shù)據(jù)結(jié)構(gòu); 在屏幕上顯示磁盤請求的服務(wù)狀況; 將一批磁盤請求的情況存磁盤文件,以后可以讀出并重放; 計算磁頭移動的總距離及平均移動距離; 支持算法:FIFO、SSTF、SCAN、CSCAN; 2.設(shè)計目的: 調(diào)度磁盤I/O請求服務(wù),采用好的方式能提高訪問時間和帶寬。本實(shí)驗(yàn)通過編程對磁盤調(diào)度算法的實(shí)現(xiàn),加深對算法的理解,同時通過用C++語言編寫程序?qū)崿F(xiàn)這些算法,并在windos平臺上實(shí)現(xiàn),更好的掌握操作系統(tǒng)的原理以及實(shí)現(xiàn)方法,提高綜合運(yùn)用專業(yè)課知識的能力。 3.任務(wù)及要求 3.1 設(shè)計任務(wù) 編程實(shí)現(xiàn)下述磁盤調(diào)度算法,并求出每種算法的平均尋道長度: 1、先來先服務(wù)算法(FCFS) 2、最短尋道時間算法(SSTF) 3、掃描算法(SCAN) 4、循環(huán)掃描算法(CSCAN) 3.2 設(shè)計要求 對用戶指定的磁盤調(diào)度請求序列,基于以上四種算法,實(shí)現(xiàn)各自的調(diào)度順序并輸出,同時計算出各種算法下的平均尋道長度。 4.算法及數(shù)據(jù)結(jié)構(gòu) 4.1算法的總體思想 queue[n] 為請求調(diào)度序列,diskrode為磁盤磁道數(shù),headstarts為正在調(diào)度的磁道 ①先來先服務(wù)算法(FCFS)按queue[n]數(shù)組的順序進(jìn)行磁盤調(diào)度,將前一個調(diào)度磁道與下一個調(diào)度磁道的差值累加起來,得到總的尋道長度,再除以n得到平均尋道長度。 ②最短尋道時間優(yōu)先算法(SSTF)將queue[n]進(jìn)行由小到大的排序,首先定位當(dāng)前調(diào)度磁headstarts在queue[n]的位置,通過循環(huán)語句找出離起始磁頭最短的位置。 ③掃描算法(SCAN) 將queue[n]進(jìn)行由小到大的排序,首先定位當(dāng)前調(diào)度磁headstarts在queue[n]的位置,然后在此位置按給定的方向遍歷queue[n],當(dāng)?shù)蓝它c(diǎn)(queue[0]或queue[n-1])時,再在定位處反向遍歷到另一端。當(dāng)調(diào)度磁道不在queue端點(diǎn)時,總的尋道長度為為前一個磁道與后一個磁 道差值的累加,當(dāng)?shù)竭_(dá)端點(diǎn)且queue[n]未全調(diào)度時,總尋道長度加上端點(diǎn)值再加上下一個調(diào)度磁道的值,再按前面的算法進(jìn)行,直到磁道全部都調(diào)度完畢,得到總的尋道長度,除以n得到平均尋道長度。 ④循環(huán)掃描算法(CSCAN)將queue[n]進(jìn)行由小到大的排序,首先定位當(dāng)前調(diào)度磁headstarts在queue[n]的位置,然后在此位置按給定的方向遍歷queue[n],當(dāng)?shù)蓝它c(diǎn)(queue[0]或queue[n-1])時,反向到另一端點(diǎn)再以此方向進(jìn)行遍歷,直到queue[n]中所有都調(diào)度完。當(dāng)調(diào)度磁道不在queue端點(diǎn)時,總的尋道長度為為前一個磁道與后一個磁道差值的累加,當(dāng)?shù)竭_(dá)端點(diǎn)且queue[n]未全調(diào)度時,總尋道長度加上端點(diǎn)值再加上磁盤磁道總長度,再加上下一個調(diào)度磁道的值,再按前面的算法進(jìn)行,直到磁道全部都調(diào)度完畢,得到總的尋道長度,除以n得到平均尋道長度。 5、源代碼: #include 1、先來先服務(wù)算法(FCFS)**********”< cout<<“****** 2、最短尋道時間優(yōu)先算法(SSTF)**********”< cout<<“****** 3、掃描算法(SCAN)**********”< cout<<“****** 4、循環(huán)掃描算法(CSCAN)**********”< cout<<“****** 5、退出 **********”< /*======================初始化序列=======================*/ void init(int queue[],int queue_copy[],int n){ int i;for(i=0;i //對當(dāng)前正在執(zhí)行的磁道號進(jìn)行定位,返回磁道號小于當(dāng)前磁道中最大的一個 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是請求調(diào)度序列,n為其個數(shù),diskroad為磁盤磁道數(shù),headstarts為正在調(diào)度的磁道 { cout<<“************以下為FCFS調(diào)度算法***********”< /*=====================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調(diào)度算法***********”< -headstarts)){ cout< /*======================以下是SCAN算法====================*/ void SCAN(int queue[], int n, int diskrode, int headstarts){ int direction, i, fixi;cout<<“***********以下是SCAN調(diào)度算法*************”< /*======================以下是CSCAN算法====================*/ void CSCAN(int queue[],int n,int diskrode,int headstarts){ int direction,i,fixi;cout<<“***********以下是CSCAN調(diào)度算法*************”< void main(){ int n, i, diskrode, headstarts;//n表示調(diào)度磁盤請求序列queue的長度,diskrode表示磁盤磁道的個數(shù),headstarts表示目前正在調(diào)度的磁道; cout<<“請輸入磁盤的總磁道數(shù):”< 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<<“程序結(jié)束,謝謝使用!”<第四篇:常用進(jìn)程調(diào)度算法的分析與評價
第五篇:操作系統(tǒng)課程設(shè)計-磁盤調(diào)度算法