廣州大學課程設計–時間片輪轉法
操作系統課程設計
要求:書寫課程設計報告,報告中應該包含如下內容:
(1)課程設計題目及內容
(2)程序中使用的數據結構及主要符號說明
(3)程序流程圖和帶有註釋的源程序
(4)執行程序名,並打印程序運行時的初值和運算結果
(5)實驗結果分析,實驗收穫和體會
(6)實驗的改進意見和建議。以下六個題目任選一題
題目一:設計一個按照時間片輪轉法實現處理機調度的程序 時間片輪轉法實現處理機調度的程序設計提示如下:
(1)假設系統有n個進程,每個進程用一個進程控制塊(PCB)來代表。進程控制塊的格式如下表所示,且參數意義也相同。
進程名 鏈接指針 到達時間 估計運行時間 進程狀態(2)按照進程到達的先後順序排成一個循環隊列,設一個隊首指針指向第一個到達進程的首址。另外再設一個當前運行進程指針,指向當前正運行的進程。
(3)執行處理機調度時,首先選擇隊首的第一個進程運行。
(4)由於本題目是模擬實驗,所以對被選中的進程並不實際啓動運行,而只是執行如下操作:
1)估計運行時間減1;
2)輸出當前運行進程的名字。
用這兩個操作來模擬進程的一次運行。
(5)進程運行一次後,以後的調度則將當前指針依次下移一個位置,指向下一個進程,即調整當前運行指針指向該進程的鏈接指針所指進程,以指示應運行進程,同時還應判斷該進程的剩餘運行時間是否爲0,若不爲0,則等待下一輪的運行,若該進程的剩餘運行時間爲0,則將該進程的狀態置爲完成狀態“C”,並退出循環隊列。
(6)若就緒隊列不爲空,則重複上述的步驟(4)和(5)直到所有進程都運行完爲止。
(7)在所設計的調度程序中,應包含顯示或打印語句,以便顯示或打印每次選中進程的名稱及運行一次後隊列的變化情況。
思路
- [Ⅰ] 先建立鏈式循環隊列,然後按照到達時間從小到大排序
- [Ⅱ] 將排好序的隊列輸入到RR算法
- [Ⅲ] 將未結束的進程的運行時間輪流減一,若有的進程結束了則標記,直至所有進程運行時間爲0。
一、程序流程圖
二、源代碼
// 課設_時間片輪轉法_處理機調度.cpp : 此文件包含 "main" 函數。程序執行將在此處開始並結束。
//
#include <iostream>
#include<stdio.h>
#include<stdlib.h>
#include<ctime>
using namespace std;
#define Length 10
int n;
int Round = 0;//輪轉數
struct PCB//一個頭指針,無數據,下一個爲頭,rear一直指向尾
{
char Name[Length];
PCB* next;
int ArriveTime;//到達時間
int RunTime;//運行時間
char state;//狀態(A爲未完成態,C爲完成態)
}*head;//頭
void Creat(PCB* c)
{
srand((unsigned)time(NULL));
PCB* l, * s;
c = (PCB*)malloc(sizeof(PCB));
c->next = NULL;
l = c;//頭節點
printf("請輸入總進程數:");
scanf_s("%d", &n);
printf("隨機生成\t序號\t初始化進程(進程名'\'到達時間'\'估計運行時間)\n");
for (int i = 0; i < n; ++i)
{
s= (PCB*)malloc(sizeof(PCB));
s->next = NULL;
/*printf("%d\t", i);
scanf_s("%s", &s->Name,sizeof(s->Name));
scanf_s("%d", &s->ArriveTime);
scanf_s("%d", &s->RunTime);*/
s->Name[0] = char(i + 65);
for (int j = 1; j < Length; ++j)
{
s->Name[j] = NULL;
}
s->ArriveTime = rand() % 10;
s->RunTime = rand()%10+1;
s->state = 'A';//未運行
l->next = s;
if (i == 0)
head = s;
l = l->next;
}
//rear = l;
l->next = head;
printf("\n");
}
void Output(PCB* c)
{
if (n == 0)
{
exit(1);
}
PCB* l;
l = c;
printf("名字\t到達時間\t估計運行時間\t狀態\n");
do
{
if (l->state != 'C')//該進程未結束
{
printf("%s\t", l->Name);
printf("%d\t\t", l->ArriveTime);
printf("%d\t\t", l->RunTime);
//cout<<l->state<<endl;
printf("%c\n", l->state);
l = l->next;
}
else
l = l->next;
} while (l != head);
printf("\n");
}
void Output2(PCB* c,int time)//輸出運行隊列
{
PCB* l;
l = c;
printf("名字\t到達時間\t估計運行時間\t狀態\n");
do
{
if (l->state != 'C'&&l->ArriveTime<=time)//該進程未結束
{
printf("%s\t", l->Name);
printf("%d\t\t", l->ArriveTime);
printf("%d\t\t", l->RunTime);
//cout<<l->state<<endl;
if (l->RunTime == 0)
{
printf("C\n");
}
else
{
printf("%c\n", l->state);
}
l = l->next;
}
else
l = l->next;
} while (l != head);
printf("\n");
}
void SortPCB(PCB* c)
{
PCB* l,*tmp,*s;
tmp=(PCB*)malloc(sizeof(PCB));
l = c;
printf("--------------------------根據到達時間排序--------------------------\n");
for(int i=0;i<n;++i)
{
s = l->next;
for(int j=0;j<n-1;++j)
{
if (s->ArriveTime > l->ArriveTime)//冒泡
{
for (int i = 0; i < Length; ++i)
{
tmp->Name[i] = l->Name[i];
}
tmp->ArriveTime = l->ArriveTime;
tmp->RunTime = l->RunTime;
tmp->state = l->state;
for (int i = 0; i < Length; ++i)
{
l ->Name[i] = s->Name[i];
}
l->ArriveTime = s->ArriveTime;
l->RunTime = s->RunTime;
l->state = s->state;
for (int i = 0; i < Length; ++i)
{
s->Name[i] = tmp->Name[i];
}
s->ArriveTime = tmp->ArriveTime;
s->RunTime = tmp->RunTime;
s->state = tmp->state;
}
s = s->next;
}
l = l->next;
}
}
void RR(PCB *c)//時間片輪轉法
{
printf("--------------------------時間片輪轉法--------------------------\n");
int m = n;//剩餘進程數
PCB* l;
l = c;
while (l->RunTime > 0)
{
printf("Round:\t%d",Round);
//把就緒隊列裏面到達時間的PCB加入運行隊列
if (l->ArriveTime <= Round)
{
printf("--正在運行%s", l->Name);
printf("進程\n");
l->RunTime--;
Output2(c,Round);
if (l->RunTime == 0)//結束了
{
l->state = 'C';
m--;
printf("進程%s已經結束,被刪除\n", l->Name);
}
/*else
{
printf("--當前沒有進程運行\n");
}*/
int count = 0;
while (l->next->ArriveTime > Round&&count!=m)//跳過未到到達時間的進程且還有到了到達時間的隊列
{
l = l->next;
count++;
}
/* 測試樣例
1 3 2
2 3 1
3 0 1
4 0 5
5 10 2
*/
l = l->next;
}
else
{
printf("--當前無進程運行\n");
}
Round++;
while (m && l->RunTime == 0)
{
l = l->next;//跳過已經結束的進程
}
}
printf("--------------------------END--------------------------\n");
}
int main()
{
printf("-----------------------------LSZNB-----------------------------\n");
PCB*c = (PCB*)malloc(sizeof(PCB));
Creat(c);
Output(head);
SortPCB(head);
Output(head);
RR(head);
}
三、運行結果
舉個簡單的例子
A 0 2
B 0 2
C 2 3
那麼順序應該是A->B->A(A退出)->B(退出)->C->C->C(退出)
這裏就展示一個簡單(隨機生成的,不是上面那個)的例子,數量太多不好截屏
四、實驗結果分析
- 因爲算法比較簡單,值得注意的地方就是要考慮數據結構(PCB)的初始化。
- 能進一步瞭解到進程的運作模式。
- 這類題目的難度較低,答辯可能會輕鬆些但是得分的上限不會很高。