西南交大操作系統實驗-進程調度
對操作系統中進程調度的模擬算法。
實驗要求實現操作系統進程調度中的SRT與FEEDBACK算法。
進程調度常見算法概要:
FCFS(先到先服務): 先來先服務,也可以稱爲先進先出
ROUND-ROBIN(輪詢): 以一個週期性間隔產生時鐘中斷,此時當前正在運行的進程被置於就緒隊列,基於FCFS選擇下一個就緒進程運行。
SPN:最短進程優先,下一次選擇所需處理時間最短的進程
SRT:最短剩餘時間優先,總是選擇預期剩餘時間最短的進程
HRRN:最高響應比優先,R=(w+s)/s,其中R表示響應比,w表示已經等待的時間,s表示期待服務的時間
FEEDBACK(反饋):進程第一次進入系統是放置於RQ0,第一次被強佔並返回就緒態時,放入RQ1,以後每次被強佔就下降一級。如果進程處於最低等級,則不再降級,反覆返回到該隊列,直到結束。
SRT具體實現原理略;
FEEDBACK實現原理:全局定義進程結構體,包括到達時間,剩餘服務時間,進程號,FEEDBACK q參數,優先級,完成狀態。再建立一個以該結構體爲元素的隊列數組,數組角標越大代表優先級越低,進程每次被分配執行時間成等比數列。
int time = pow(pro.tq, pro.priority);//tq爲公比,priority爲優先級
若q=1則每次分配時間爲1。進程用完本次分配時間若未完成,則進入下一個低優先級隊列(上圖q=2時A第二次執行只被分配了1個時間片,具體原因不明,我猜測是當A第一次執行完成後,除了它自己沒有別的進程在等待,所以又被放進了原隊列,如有錯誤請指正),有一點需要注意的是當有新進程到達後,當前正在運行的進程使用完被分配的時間片後會被最新的進程搶佔,即永遠最高優先級優先,算法實現可以檢測當有新進程到達時,將隊列數組角標重置爲零。
FIFO,ROUNDROBIN代碼參見課程資源示例程序。
FEEDBACKANDSRT源代碼:
/*
Title:FEEDBACKANDSRT
Author:Uranuslight
School:SWJTU
Build Date:2017/05/15
Last revision:2017/05/16
Version:1.2
*/
#include "iostream"
#include "cstdlib"
#include "vector"
#include "map"
#include "deque"
#include "sstream"
#include "cstdio"
#include "cmath"
#include "cstring"
#include "ctime"
#include "queue"
#include "fstream"
#include "iomanip"
#define MAXN 20
#define ll long long
#define mst(ss,b) memset(ss,b,sizeof(ss))
using namespace std;
bool state[5][20];
int clocks = 0;
int totalExcuteTime = 0;
bool newflag = false;//new process coming change to true
typedef struct process
{
int start;//start time
int remain;//service time
int pid;//id of process
int tq;//min time slice
int priority;//
int done;
};
process p[5];
queue <process> que[MAXN];
bool isnewarrived()
{
for (int i = 0; i<5; i++)
{
if (p[i].start == clocks)
{
que[0].push(p[i]);
newflag = true;
return true;
}
}
return false;
}
bool isallqueueempty()
{
bool flag = true;
for (int i = 0; i<MAXN; i++)
flag &= que[i].empty();
return flag;
}
bool runprocess(process &pro, int &clocks)
{
int time = pow(pro.tq, pro.priority);
bool breakflag = false;
do
{
while (time && pro.remain && !breakflag)
{
time--; pro.remain--;
state[pro.pid][clocks++] = true;
isnewarrived();
}
if (breakflag) break;
if (pro.remain>0)
return false;
else
return true;
} while (0);
}
void init(int tq)
{
p[0].start = 0; p[0].remain = 3;
p[1].start = 2; p[1].remain = 6;
p[2].start = 4; p[2].remain = 4;
p[3].start = 6; p[3].remain = 5;
p[4].start = 8; p[4].remain = 2;
for (int i = 0; i<5; i++)
{
p[i].pid = i;
p[i].priority = 0;
p[i].tq = tq;
p[i].done = 0;
}
}
void printinfo()
{
cout << "task id start excute" << endl;
for (int i = 0; i<5; i++)
{
printf("task %2d: %6d %6d\n", i + 1, p[i].start, p[i].remain);
}
}
void printans()
{
for (int i = 0; i<5; i++)
{
for (int j = 0; j<20; j++)
{
if (state[i][j])
cout << "#";
else
cout << " ";
}
cout << endl;
}
cout << endl;
}
void Feedback(int tq)
{
init(tq);
mst(state, false);
clocks = 0;
int i = 0;
int executeflag = 0;
{
que[0].push(p[0]);
while (i < 20)
{
while (!que[i].empty())
{
process ptemp = que[i].front();
que[i].pop();
if (!runprocess(ptemp, clocks))
{
executeflag = 1;
if(!isallqueueempty())
{
ptemp.priority++;
que[i + 1].push(ptemp);
}
else que[i].push(ptemp);
}
if (newflag)
{
break;
}
}
i++;
if (!isallqueueempty() && executeflag == 1 || newflag)
{
i = 0; executeflag = 0; newflag = false;
}
if (clocks == 20)
break;
}
}
cout << "Slice q: " << p[0].tq << endl;
printans();
}
void SRT()
{
init(1);
mst(state, false);
for (int j = 0; j<20; j++)
{
int minre = 9999, pos=0;
for (int i = 0; i<5; i++)
{
if (minre>p[i].remain && j >= p[i].start && p[i].remain>0)
{
minre = p[i].remain;
pos = i;
}
}
state[pos][j] = true;
p[pos].remain = p[pos].remain - 1;
}
printans();
}
int main()
{
char choice;
while (1)
{
//system("cls");
printf("please choice the schedule measure:\n");
printf("f : Feedback\n");
printf("s : SRT\n");
printf("q : Exit\n");
printf("choice = ");
choice = getchar();
if (choice == '\n')
choice = getchar();
switch (choice)
{
case 'f': init(1);printinfo();Feedback(1); Feedback(2); break;
case 's': init(1);printinfo();SRT(); break;
case 'q': return 0;
default:
{
cout << "please input the true symbol(p or f or r)!" << endl;
continue;
}
}
cout << endl;
//system("pause");
}
return 0;
}