作業系統(Linux)--按優先數排程演算法實現處理器排程

yill_h發表於2016-11-28

這道題慢悠悠地做,出現了很多錯誤,大多都是空指標產生的中斷,最後還是實現了,程式碼寫得有點亂,有時間優化下(當然有同學指點下也是不錯的,哈哈)。


實習題目:

設計一個按優先數排程演算法實現處理器排程的程式。

[提示]:

(1) 假定系統有5個程式,每個程式用一個PCB來代表。PCB的格式為:

程式名、指標、要求執行時間、優先數、狀態。

程式名——P1~P5。

指標——按優先數的大小把5個程式連成佇列,用指標指出下一個程式PCB的首地址。

要求執行時間——假設程式需要執行的單位時間數。

優先數——賦予程式的優先數,排程時總是選取優先數大的程式先執行。

狀態——假設兩種狀態,就緒,用R表示,和結束,用E表示。初始狀態都為就緒狀態。

(2) 每次執行之前,為每個程式任意確定它的“優先數”和“要求執行時間”。

(3) 處理器總是選隊首程式執行。採用動態改變優先數的辦法,程式每執行1次,優先數減1,要求執行時間減1。

(4) 程式執行一次後,若要求執行時間不等於0,則將它加入佇列,否則,將狀態改為“結束”,退出佇列。

(5) 若就緒佇列為空,結束,否則,重複(3)。


思路流程圖:









對執行時間的判斷:


對優先數的判斷:





/*
author:huangpingyi
date:2016 11 24
*/
#include <iostream>
#include <time.h>
#include <stdlib.h>
using namespace std;

static int point = 0;//用於計算程式是否執行完成
struct PCB
{
	int pid;
	int priority;
	int time;
	PCB *next;
};

void tailCreate(PCB *L)
{
	srand((unsigned int)time(0));//以時間為隨機數種子,保證每次隨機數不一樣
	int priority = rand() % 5;//隨機優先數
	PCB *s, *r = L;
	for (int i = 0; i<5; i++)
	{
		
		//隨機時間為1到50
		int number = rand() % 5;
		while (number == 0)
			//如果是0就一直隨機,直到出現不是0的為止
			number = rand() % 5;
		//tail_insert用尾插法初始化
		s = new PCB;
		s->pid = i + 1;
		s->priority = (i + priority) % 5 + 1;
		s->time = number;
		if (s->priority != 5 || r->next == NULL)//如果r->next==NULL表示為佇列只有一個頭結點,就直接插入
		{
			r->next = s;
			r = s;
		}
		if ((s->priority == 5) && (r->next != NULL))//如果佇列不為空,就將它放在頭結點後面
		{
			s->next = L->next;
			L->next = s;
		}
	}
	r->next = NULL;
}

void run(PCB *L)//執行
{
	PCB *c = L;
	PCB *p = L;

	for (L; L; L = L->next)
	{
		if (L->next == NULL)
			break;
		//由於存在存在頭結點,所以從L->next開始
		L->next->priority = L->next->priority - 1;
		L->next->time = L->next->time - 1;
		if (L->next->time == 0)
			//如果執行時間為0,就將它移除佇列中
		{
			cout << "run over" <<"->PID->"<< L->next->pid << endl;
			L->next->time = -1;
			L->next = L->next->next;
			//由於出現了L->next = L->next->next;這步,
			//接著執行for迴圈的第三個表示式,便跳過了L->next->next這個結點,接著執行L->next->next->next這個結點
			//所以需要判斷一下L->next->next這個結點
			if (L->next != NULL&&L->next->time != 0)
			{
				L->next->priority = L->next->priority - 1;
				L->next->time = L->next->time - 1;
			}


				//如果L->next->next->time的值等於0,便會將它移除佇列,接著執行L->next=L->next->next這步
				//所以需要while迴圈來判斷
				while (L->next != NULL&&L->next->time == 0)
				{
					cout << "run over" <<"->PID->"<< L->next->pid << endl;
					L->next->time = -1;
					L->next = L->next->next;
					point = point + 1;
					if (L->next != NULL)
					{
						L->next->priority = L->next->priority - 1;
						L->next->time = L->next->time - 1;
					}
				}
			point = point + 1;
		}
		if (L->next != NULL&&L->next->priority == 0)//如果優先數為0就將它變成0放在隊首
		{
			//******
			PCB *q = L->next;
			L->next = L->next->next;
			q->priority = 5;
			q->next = c->next;
			c->next = q;
			//由於執行了L->next=L->next->next
			//所以又會執行上面那步同樣地操作
			if (L->next != NULL&&L->next->time != 0)
			{
				L->next->priority = L->next->priority - 1;
				L->next->time = L->next->time - 1;
			}
			while (L->next != NULL&&L->next->time == 0)
			{
				cout << "run over" << "->PID->"<<L->next->pid << endl;
				L->next->time = -1;
				L->next = L->next->next;
				point = point + 1;
				if (L->next != NULL)
				{
					L->next->priority = L->next->priority - 1;
					L->next->time = L->next->time - 1;
				}
			}
		}


	}
	L = p;
}

int main()
{
	PCB *L, *m;
	L = new PCB;//初始化頭結點
	L->next = NULL;
	tailCreate(L);
	m = L;
	L = L->next;

	cout << "=============" << endl;
	cout << "Init" << endl;
	cout << "==============" << endl;
	for (L; L; L = L->next)
	{
		cout <<"PID :"<< L->pid << endl;
		cout << "Time :"<<L->time << endl;
		cout << "Priority :"<<L->priority << endl;
		cout << "******* " << endl;
		cout << endl;
	}
	cout << "=============" << endl;
	cout << "Init successful!" << endl;
	cout << "==============" << endl;
	cout << endl;
	cout << "run order!" << endl;
	while (point != 5)
	{
		run(m);
	}
	system("pause");
	return 0;

}


windows下:




ubuntu:





這裡用了srand((unsigned int)time(0));函式以電腦時間為隨機數種子,保證每次隨機數不一樣

這裡設定的執行時間為1到5

相關文章