操作系统课程设计--模拟时间片轮转法
課程設(shè)計(jì)題目
設(shè)計(jì)一個(gè)按照時(shí)間片輪轉(zhuǎn)法實(shí)現(xiàn)處理機(jī)調(diào)度的程序。
實(shí)驗(yàn)內(nèi)容
(1) 假設(shè)系統(tǒng)有n個(gè)進(jìn)程,每個(gè)進(jìn)程用一個(gè)進(jìn)程控制塊(PCB)來代表。進(jìn)程控制塊的格式如下表所示,且參數(shù)意義也相同。
| 鏈接指針 |
| 到達(dá)時(shí)間 |
| 估計(jì)運(yùn)行時(shí)間 |
| 進(jìn)程狀態(tài) |
(2) 按照進(jìn)程到達(dá)的先后順序排成一個(gè)循環(huán)隊(duì)列,設(shè)一個(gè)隊(duì)首指針指向第一個(gè)到達(dá)進(jìn)程的首址。另外再設(shè)一個(gè)當(dāng)前運(yùn)行進(jìn)程指針,指向當(dāng)前正運(yùn)行的進(jìn)程。
(3) 執(zhí)行處理機(jī)調(diào)度時(shí),首先選擇隊(duì)首的第一個(gè)進(jìn)程運(yùn)行。
(4) 由于本題目是模擬實(shí)驗(yàn),所以對(duì)被選中的進(jìn)程并不實(shí)際啟動(dòng)運(yùn)行,而只是執(zhí)行如下操作:
1)估計(jì)運(yùn)行時(shí)間減1;
2)輸出當(dāng)前運(yùn)行進(jìn)程的名字。
用這兩個(gè)操作來模擬進(jìn)程的一次運(yùn)行。
(5) 進(jìn)程運(yùn)行一次后,以后的調(diào)度則將當(dāng)前指針依次下移一個(gè)位置,指向下一個(gè)進(jìn)程,即調(diào)整當(dāng)前運(yùn)行指針指向該進(jìn)程的鏈接指針?biāo)高M(jìn)程,以指示應(yīng)運(yùn)行進(jìn)程,同時(shí)還應(yīng)判斷該進(jìn)程的剩余運(yùn)行時(shí)間是否為0,若不為0,則等待下一輪的運(yùn)行,若該進(jìn)程的剩余運(yùn)行時(shí)間為0,則將該進(jìn)程的狀態(tài)置為完成狀態(tài)“C”,并退出循環(huán)隊(duì)列。
(6) 若就緒隊(duì)列不為空,則重復(fù)上述的步驟(4)和(5)直到所有進(jìn)程都運(yùn)行完為止。
(7) 在所設(shè)計(jì)的調(diào)度程序中,應(yīng)包含顯示或打印語句,以便顯示或打印每次選中進(jìn)程的名稱及運(yùn)行一次后隊(duì)列的變化情況。
算法流程圖
使用的數(shù)據(jù)結(jié)構(gòu)及主要符號(hào)說明
本實(shí)驗(yàn)使用了一個(gè)結(jié)構(gòu)表示進(jìn)程控制塊(PCB),其所有的屬性以及含義如下:
typedef struct PCB //PCB結(jié)構(gòu) {int name; //進(jìn)程名字int arrivalTime; //進(jìn)程到達(dá)時(shí)間int needTime; //進(jìn)程需要運(yùn)行的時(shí)間int serverTime; //進(jìn)程已經(jīng)運(yùn)行的時(shí)間int leftSysTime; //進(jìn)程結(jié)束時(shí)系統(tǒng)時(shí)間int flag; //進(jìn)程狀態(tài),(1-已完成,0-未完成)struct PCB* next; //鏈接指針 }PCB;為了方便整個(gè)流程的操作,本實(shí)驗(yàn)使用了鏈?zhǔn)疥?duì)列對(duì)進(jìn)程的操作。下面的initQueue隊(duì)列是保存初始化得到的進(jìn)程,每個(gè)進(jìn)程按照“進(jìn)程到達(dá)時(shí)間”升序排列initQueue隊(duì)列中。而readyQueue隊(duì)列是進(jìn)程的就緒隊(duì)列,系統(tǒng)在readyQueue隊(duì)列的隊(duì)頭取一個(gè)進(jìn)程運(yùn)行,根據(jù)系統(tǒng)時(shí)間從initQueue隊(duì)列中取出到達(dá)時(shí)間合適的進(jìn)程插到readyQueue隊(duì)列的隊(duì)尾,然后再將剛剛運(yùn)行完的進(jìn)程插入到隊(duì)尾。endQueue隊(duì)列是用來存放已經(jīng)運(yùn)行結(jié)束的進(jìn)程,此隊(duì)列用于計(jì)算平均周轉(zhuǎn)時(shí)間和平均帶權(quán)周轉(zhuǎn)時(shí)間。
typedef struct PCBQueue //隊(duì)列 {struct PCB* front; //指向隊(duì)頭struct PCB* rear; //指向隊(duì)尾 }PCBQueue;PCBQueue* initQueue = (PCBQueue*)malloc(sizeof(PCBQueue)); //初始化隊(duì)列 PCBQueue* readyQueue = (PCBQueue*)malloc(sizeof(PCBQueue)); //就緒隊(duì)列 PCBQueue* endQueue = (PCBQueue*)malloc(sizeof(PCBQueue)); //已經(jīng)結(jié)束的進(jìn)程隊(duì)列源代碼
//RoudRobin.c #include<stdio.h> #include<stdlib.h> #include<time.h>typedef struct PCB //PCB結(jié)構(gòu) {int name; //進(jìn)程名字int arrivalTime; //進(jìn)程到達(dá)時(shí)間int needTime; //進(jìn)程需要運(yùn)行的時(shí)間int serverTime; //進(jìn)程已經(jīng)運(yùn)行的時(shí)間int leftSysTime; //進(jìn)程結(jié)束時(shí)系統(tǒng)時(shí)間int flag; //進(jìn)程狀態(tài),(1-已完成,0-未完成)struct PCB* next; //鏈接指針 }PCB;typedef struct PCBQueue //隊(duì)列 {struct PCB* front; //指向隊(duì)頭struct PCB* rear; //指向隊(duì)尾 }PCBQueue;int systime; //系統(tǒng)運(yùn)行時(shí)間 int processes; //進(jìn)程個(gè)數(shù)//初始化數(shù)據(jù) PCBQueue* Init() {srand(time(NULL));processes = rand() % 15 + 5; //隨機(jī)初始化processes個(gè)進(jìn)程個(gè)數(shù)systime = 0;PCBQueue* initQueue = (PCBQueue*)malloc(sizeof(PCBQueue)); //初始化隊(duì)列if (!initQueue)exit(-1);initQueue->front = initQueue->rear = NULL;PCB* p = (PCB*)malloc(sizeof(PCB)); //初始化隊(duì)列添加一個(gè)頭節(jié)點(diǎn)if (!p)exit(-1);p->arrivalTime = -1;p->next = NULL;initQueue->front = initQueue->rear = p;for (int i = 1; i <= processes; i++){p = (PCB*)malloc(sizeof(PCB)); //初始化隊(duì)列添加進(jìn)程p->name = i; //進(jìn)程的名字if (i <= 2) //進(jìn)程到達(dá)的時(shí)間p->arrivalTime = rand() % i;elsep->arrivalTime = rand() % (i + 7);p->needTime = rand() % 5 + 2; //進(jìn)程需要運(yùn)行的時(shí)間p->flag = 0;p->serverTime = 0;PCB* temp = initQueue->front;while (temp) //根據(jù)新生成的PCB在初始化隊(duì)列initQueue中找到合適的位置{if (p->arrivalTime >= temp->arrivalTime){initQueue->rear = temp;temp = temp->next;}elsebreak;}//將新生成的PCB插入到初始化隊(duì)列initQueue中合適的位置p->next = temp;initQueue->rear->next = p;initQueue->rear = initQueue->front;}//打印printf("申請(qǐng)CPU的進(jìn)程名、到達(dá)時(shí)間、運(yùn)行時(shí)間如下:\n");printf("進(jìn)程 到達(dá)時(shí)間 運(yùn)行時(shí)間\n");for (int i = 0; i < processes; i++){initQueue->rear = initQueue->rear->next;if (initQueue->rear)printf("p%-3d %6d %10d\n", initQueue->rear->name, initQueue->rear->arrivalTime, initQueue->rear->needTime);}printf("\n");//刪除多余的頭節(jié)點(diǎn)p = initQueue->front;initQueue->rear = initQueue->front = initQueue->front->next;free(p);return initQueue; }//在初始化隊(duì)列中找出某個(gè)系統(tǒng)時(shí)間剛好到達(dá)的進(jìn)程放到就緒隊(duì)列中 void Fine(PCBQueue* initQueue, PCBQueue* readyQueue) {while (initQueue->front != NULL) //遍歷就緒隊(duì)列{if (initQueue->front->arrivalTime == systime) //將就緒隊(duì)列中‘當(dāng)前系統(tǒng)時(shí)間’的進(jìn)程添加到就緒隊(duì)列{if (readyQueue->front == NULL){readyQueue->front = readyQueue->rear = initQueue->front;initQueue->front = initQueue->front->next;readyQueue->rear->next = NULL;}else{readyQueue->rear->next = initQueue->front;readyQueue->rear = initQueue->front;initQueue->front = initQueue->front->next;readyQueue->rear->next = NULL;}}elsebreak;} }void CalTime(PCBQueue* e) {PCB* p;int turnoverTime = 0, temp1; //平均周轉(zhuǎn)時(shí)間float turnoverTimeAvg = 0, temp2; //平均帶權(quán)周轉(zhuǎn)時(shí)間printf("所有進(jìn)程運(yùn)行結(jié)束!\n\n");printf("------------------時(shí)間片輪轉(zhuǎn)法性能指標(biāo)------------------\n");printf("進(jìn)程名 到達(dá)時(shí)間 運(yùn)行時(shí)間 結(jié)束時(shí)間 周轉(zhuǎn)時(shí)間 帶權(quán)周轉(zhuǎn)時(shí)間\n");while (e->front){temp1 = e->front->leftSysTime - e->front->arrivalTime;temp2 = (float)temp1 / e->front->needTime;turnoverTime += temp1; //平均周轉(zhuǎn)時(shí)間turnoverTimeAvg += temp2; //平均帶權(quán)周轉(zhuǎn)時(shí)間printf(" p%-3d %5d %7d %9d %9d %15f\n", e->front->name, e->front->arrivalTime, e->front->needTime, e->front->leftSysTime, temp1, temp2);p = e->front;e->front = e->front->next;free(p);}printf("平均周轉(zhuǎn)時(shí)間:%f,平均帶權(quán)周轉(zhuǎn)時(shí)間:%f\n", (float)turnoverTime / processes, turnoverTimeAvg / processes); }//模擬執(zhí)行 void SimRun(PCBQueue* initQueue) {PCBQueue* endQueue = (PCBQueue*)malloc(sizeof(PCBQueue)); //已經(jīng)結(jié)束的進(jìn)程隊(duì)列if (!endQueue)exit(-1);endQueue->rear = endQueue->front = NULL;PCBQueue* readyQueue = (PCBQueue*)malloc(sizeof(PCBQueue)); //就緒隊(duì)列if (!readyQueue)exit(-1);readyQueue->rear = readyQueue->front = NULL;Fine(initQueue, readyQueue); //從初始化隊(duì)列找出現(xiàn)在系統(tǒng)時(shí)間到達(dá)的進(jìn)程放到就緒隊(duì)列printf("以上所有進(jìn)程運(yùn)行過程和每時(shí)刻進(jìn)程就緒隊(duì)列情況如下:\n");while (initQueue->front || readyQueue->front){if (readyQueue->front) //就緒隊(duì)列不為空{PCB* p = readyQueue->front;printf("系統(tǒng)時(shí)間:%d\t正在運(yùn)行的進(jìn)程:p%-3d 就緒隊(duì)列:", systime, p->name); //打印正在執(zhí)行的進(jìn)程、就緒隊(duì)列p = readyQueue->front->next;while (p){printf("p%-2d ", p->name);p = p->next;}printf("\n");p = readyQueue->front;p->serverTime += 1;systime += 1;Fine(initQueue, readyQueue); //進(jìn)程運(yùn)行完后理論上要進(jìn)行“保護(hù)現(xiàn)場(chǎng)”,所以應(yīng)該先讓這個(gè)時(shí)刻到達(dá)的進(jìn)程插入就緒隊(duì)列最后if (p->needTime == p->serverTime) //該進(jìn)程已經(jīng)運(yùn)行完了{p->leftSysTime = systime;p->flag = 1; //進(jìn)程狀態(tài)改變readyQueue->front = readyQueue->front->next;p->next = NULL;if (endQueue->front == NULL){endQueue->front = endQueue->rear = p;}else{endQueue->rear->next = p;endQueue->rear = p;}}else //進(jìn)程還沒執(zhí)行完,插入到就緒隊(duì)列最后{if (readyQueue->front != readyQueue->rear){readyQueue->front = readyQueue->front->next;readyQueue->rear->next = p;readyQueue->rear = p;readyQueue->rear->next = NULL;}elsereadyQueue->front = readyQueue->rear;}}else if (initQueue->front) //就緒隊(duì)列為空,初始化隊(duì)列不為空{printf("系統(tǒng)時(shí)間:%d\t正在運(yùn)行的進(jìn)程:無 等待隊(duì)列:無\n", systime);systime += 1;Fine(initQueue, readyQueue);}else //就緒隊(duì)列、初始化隊(duì)列均為空break;}CalTime(endQueue); //計(jì)算周轉(zhuǎn)時(shí)間free(readyQueue); //釋放內(nèi)存free(initQueue);free(endQueue); }void main() {PCBQueue* initQueue = NULL;int number = 1;while (number != 3){printf("----------時(shí)間片輪轉(zhuǎn)法----------\n");printf("1.運(yùn)行時(shí)間片輪轉(zhuǎn)法算法\n");printf("2.清空屏幕\n");printf("3.退出程序\n");scanf_s("%d", &number);switch (number){case 1:initQueue = Init(); //返回按照進(jìn)程到達(dá)的先后順序排成一個(gè)隊(duì)列SimRun(initQueue); //模擬運(yùn)行printf("\n");break;case 2:system("clear");break;case 3:break;default:printf("輸入錯(cuò)誤\n");}} }實(shí)驗(yàn)結(jié)果截圖
實(shí)驗(yàn)分析
輸出結(jié)果說明:系統(tǒng)時(shí)間:是用來記錄模擬記錄進(jìn)程到達(dá)時(shí)間和進(jìn)程運(yùn)行時(shí)間,時(shí)間片輪轉(zhuǎn)開始的時(shí)候設(shè)時(shí)間為0,每個(gè)進(jìn)程運(yùn)行一個(gè)時(shí)間片時(shí)系統(tǒng)時(shí)間加1;正在運(yùn)行的進(jìn)程:是指從就緒隊(duì)列中取出合適的進(jìn)程運(yùn)行;就緒隊(duì)列:是指這個(gè)時(shí)間(系統(tǒng)時(shí)間)去掉剛?cè)〕龅倪\(yùn)行的進(jìn)程,剩余在等待運(yùn)行的進(jìn)程的隊(duì)列。
根據(jù)最后一個(gè)實(shí)驗(yàn)結(jié)果,進(jìn)程P1、是在系統(tǒng)時(shí)間為0時(shí)刻就到達(dá)了,這個(gè)時(shí)候先將進(jìn)程P1從初始化隊(duì)列initQueue取出并且插到就緒隊(duì)列readyQueue中,接著從就緒隊(duì)列readyQueue隊(duì)頭取出進(jìn)程P1,P1運(yùn)行一個(gè)時(shí)間片,系統(tǒng)時(shí)間+1,P1結(jié)束后查看P1的運(yùn)行時(shí)間是否已經(jīng)滿足,如果滿足則改變進(jìn)程狀態(tài)并且移出就緒隊(duì)列;否則查看初始化隊(duì)列有沒有進(jìn)程到達(dá)時(shí)間與系統(tǒng)時(shí)間相等,有則取出插入到就緒隊(duì)列后面,沒有就直接將剛剛運(yùn)行的還沒結(jié)束的進(jìn)程插入到就緒隊(duì)列后面。如此重復(fù)。例如最后一個(gè)實(shí)驗(yàn)結(jié)果中系統(tǒng)時(shí)間為第1秒時(shí),進(jìn)程P1運(yùn)行結(jié)束了,這個(gè)時(shí)候進(jìn)程P2到達(dá)了,而P2應(yīng)該先插入到就緒隊(duì)列后面,然后如果P1還沒滿足運(yùn)行時(shí)間就插在就緒隊(duì)列最后面,即P2后面。
本實(shí)驗(yàn)通過初始化得到一個(gè)進(jìn)程等待隊(duì)列,模擬進(jìn)程在不同時(shí)間申請(qǐng)CPU資源,通過一個(gè)就緒隊(duì)列模擬進(jìn)程的調(diào)度、執(zhí)行過程。通過大量的實(shí)驗(yàn)結(jié)果驗(yàn)證得到該程序正確地實(shí)現(xiàn)了時(shí)間片輪轉(zhuǎn)算法模擬。
實(shí)驗(yàn)收獲和體會(huì)
通過這次課程設(shè)計(jì),我對(duì)時(shí)間片輪轉(zhuǎn)調(diào)度算法進(jìn)行了大量的資料查詢,從而對(duì)時(shí)間片輪轉(zhuǎn)調(diào)度算法思想有了更深的理解,對(duì)該算法的操作也有了熟練的操作;另外通過大量的鏈表操作,我對(duì)鏈表的知識(shí)有了更深的理解,而且鍛煉了我的思維能力,我能更全面地思考問題。
時(shí)間片輪轉(zhuǎn)算法是系統(tǒng)將所有的就緒進(jìn)程按先來先服務(wù)算法的原則,排成一個(gè)隊(duì)列,每次調(diào)度時(shí),系統(tǒng)把處理機(jī)分配給隊(duì)列首進(jìn)程,并讓其執(zhí)行一個(gè)時(shí)間片。當(dāng)執(zhí)行的時(shí)間片用完時(shí),由一個(gè)計(jì)時(shí)器發(fā)出時(shí)鐘中斷請(qǐng)求,調(diào)度程序根據(jù)這個(gè)請(qǐng)求停止該進(jìn)程的運(yùn)行,將它送到就緒隊(duì)列的末尾,再把處理機(jī)分給就緒隊(duì)列中新的隊(duì)列首進(jìn)程,同時(shí)讓它也執(zhí)行一個(gè)時(shí)間片。
實(shí)驗(yàn)的改進(jìn)意見和建議。
該實(shí)驗(yàn)的提示中做給的進(jìn)程控制塊(PCB)的格式中“進(jìn)程狀態(tài)”這一屬性其實(shí)在本次模擬實(shí)驗(yàn)中用處不大,因?yàn)槿绻粋€(gè)進(jìn)程運(yùn)行完后,可以直接從就緒隊(duì)列中刪除掉,而不需要更改這個(gè)“進(jìn)程狀態(tài)”,更改后又不起作用;而且刪除后就緒隊(duì)列就會(huì)減短,遍歷的時(shí)候可以省略掉對(duì)每個(gè)進(jìn)程是否已經(jīng)結(jié)束的判斷,從而減少運(yùn)行時(shí)間。
總結(jié)
以上是生活随笔為你收集整理的操作系统课程设计--模拟时间片轮转法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: html背景边框特效代码,纯JS实现动态
- 下一篇: java信息管理系统总结_java实现科