操作系统:动态最大优先数优先的调度算法 先来先服务 短进程优先 时间片轮转调度

需求分析

进程控制块PCB的信息:

  • 进程名ID ----进程标示数
  • 优先数Priority,----优先数越大优先权越高
  • 到达时间 arrivalTime----进程的到达时间为进程输入的时间
  • 进程还需要运行时间----AllTime
  • 已用CPU时间----CPUTim
  • 进程的阻塞时间StartBlock----表示当进程在运行StartBlock个时间片后,进程将进入阻塞状态
  • 进程的阻塞时间StartTime----表示当进程阻塞StartTime个时间片后,进程将进入就绪状态
  • 进程状态----State 有Ready Waiting Running Block
  • 队列指针----Next,用来将PCB排成队列

代码:

  1. 公共数据结构和函数
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<string>
#include<ctime>
#include<sstream>
#include<fstream>
using namespace std;


const int BLOCK_NUM = 3;    // 运行BLOCK_NUM 后 阻塞
const int START_NUM = 3;    // 阻塞后经历 START_NUM 时间片后,唤醒
const int ADD_PRIORITY = 1;   // 增加的优先级
const int SUB_PRIORITY = 3;  // 减去的优先级
const int TIME_LIMIT = 1;   // 时间片
double TIME = 0;  // 程序运行的时间轴
ofstream fout;
int SEEK = 0;

class PCB {
public:
	string ID;      // 进程名
	int priority;   // 进程优先级
	string state;   // 进程状态
	double arrivalTime;  //到达时间
	double allTime;  // 进程还需运行的时间
	double CPUTime; //  已经运行的时间
	double startBlock;   // 进程运行StartBlock时间片后,将进入阻塞状态
	double startTime; 	 // 进程阻塞startTIme时间片后, 进入就绪状态
	double totalTime;  //  运行的总时间
	int blockCount;   // 记录阻塞次数
	int wakeupCount;  // 记录唤醒次数
	PCB* next;      // 指向下一个的指针

	friend istream& operator>>(istream& is, PCB& pcb);
	friend ostream& operator<<(ostream& os, const PCB& pcb);
	PCB() {
		this->state = "";
		this->CPUTime = 0;
		this->startTime = 0;
		this->startBlock = 0;
		this->wakeupCount = 0;
		this->blockCount = 0;
		this->next = NULL;
	}
	PCB(string _ID, int _priority, double _arrivalTime, double _allTime) :
		ID(_ID), priority(_priority), arrivalTime(_arrivalTime), allTime(_allTime) {

		this->state = "";
		this->CPUTime = 0;
		this->startTime = 0;
		this->startBlock = 0;
		this->wakeupCount = 0;
		this->blockCount = 0;
		this->next = NULL;
		this->totalTime = this->allTime;
	}
	
};

// 重载流提取运算符
ostream& operator<<(ostream& os, const PCB& pcb) {
	os << "  进程名: " << pcb.ID << ", 优先级: " << pcb.priority
		<< ", 到达时间: " << pcb.arrivalTime << ", 进程状态: "
		<< pcb.state << ", 已经运行的时间: " << pcb.CPUTime << ", 还需运行的时间: " << pcb.allTime
		<< ", 运行的总时间: " << pcb.totalTime
		<< ", startTime: " << pcb.startTime << ", startBlock: "
		<< pcb.startBlock << endl
		<< "\t" << " 阻塞次数: " << pcb.blockCount
		<< ", 唤醒次数: " << pcb.wakeupCount << endl;
	return os;
}

int getRandInt(int m, int n, int seek);   // 获取  [m, n)范围内的随机整数

istream& operator>>(istream& is, PCB& pcb) {

	// 功能  优先级 20 - 50;
	// 到达时间 1 - 100 之间到达
	// 运行时间 4 - 50

	int start_priority = 20;
	int end_priority = 50;
	int start_arrivalTime = 1;
	int end_arrivalTime = 10;
	int start_runTime = 5;
	int end_runTime = 10;

	//	cout << "\t输入进程的名字: " << endl << "\t";
	fout << "\t输入进程的名字: " << endl << "\t";
	//	cin >> pcb.ID;

	// ID的输入
	stringstream ss;
	ss << "__" << SEEK + 1 << "__";
	pcb.ID = ss.str();
	fout << pcb.ID << endl;

	//	cout << "\t输入进程优先级: " << endl << "\t";
	fout << "\t输入进程优先级: " << endl << "\t";
	//	cin >> pcb.priority;
	pcb.priority = getRandInt(start_priority, end_priority, SEEK);
	fout << pcb.priority << endl;

	//	cout << "\t输入进程到达的时间: " << endl << "\t";
	fout << "\t输入进程到达的时间: " << endl << "\t";
	//	cin >> pcb.arrivalTime;
	pcb.arrivalTime = getRandInt(start_arrivalTime, end_arrivalTime, SEEK);
	fout << pcb.arrivalTime << endl;

	//	cout << "\t输入进程运行的总时间: " << endl << "\t";
	fout << "\t输入进程运行的总时间: " << endl << "\t";
	//	cin >> pcb.allTime;
	pcb.allTime = getRandInt(start_runTime, end_runTime, SEEK);

	pcb.totalTime = pcb.allTime;
	fout << pcb.allTime << endl;

	return is;
}


// 状态链表
PCB* running = NULL;  // 正在运行的PCB, 规定只有一个
PCB* blocking = NULL;  //
PCB* ready = NULL;     // 按照优先级进行排序的队列
PCB* finish = NULL;
PCB* waiting = NULL;   // 按照到达时间进行排序的队列

//==================================================
// 公共函数

void insertPCBToWaitingByarrivalTime(PCB* p); //输入时, 按照到达时间进行排序, 加入到waiting 队列中
void insertFromWaitingToReady(void (*func)(PCB *p));  // 将满足到达的进程根据不同的要求插入到Ready队列中
void inputPCB();   // 输入PCB的信息
void displayPCB(string s); // 展示PCB的状态  s 可以传入窗台
void displayPCBOfWaiting();
void displayPCBOfBlock();
void displayFinishPCB();  // PCB完成的时候, 输出PCB
void destroyPCB(); // 程序完成后, 从running队列中 退出
string getFileName(string algoName);   // 根据系统的时间获取文件的

int getRandInt(int m, int n, int seek) {
	// 产生 m <= num < n的随机数
	// 随机数种子
	srand((unsigned)time(NULL) * seek);
	// 模除加加法计算 [m, n) 的随机整数
	int randint = rand() % (n - m) + m;
	return randint;
}

void displayPCBOfWaiting() {
	PCB* pW = waiting;
	cout << endl;
	fout << endl;
	cout << "\t\t---------------------正在等待的PCB: -------------------" << endl;
	fout << "\t\t---------------------正在等待的PCB: -------------------" << endl;

	while (pW != NULL) {
		cout << *pW << endl;
		fout << *pW << endl;
		pW = pW->next;
	}
	//	cout << "\t\t---------------------正在等待的PCB: -------------------" << endl;

	cout << "\t\t====================================================" << endl;
	cout << endl;
	fout << endl;
}

void displayPCBOfBlock() {
	PCB* pB = blocking;
	cout << endl;
	fout << endl;
	cout << "\t\t---------------------已被阻塞的PCB: -------------------" << endl;
	fout << "\t\t---------------------已被阻塞的PCB: -------------------" << endl;

	while (pB != NULL) {
		cout << *pB << endl;
		fout << *pB << endl;
		pB = pB->next;
	}
	cout << endl;
	fout << endl;
}

string getFileName(string algoName) {
	// 获取时间 time_t是一个64位的整型。记录的是从1970-01-01 00:00:00到现在经过的时间,精度只能到秒
	time_t now = time(0);
	struct tm t;

	localtime_s(&t, &now);

	// 将信息输出到字符串流
	stringstream ss;
	ss << algoName << "LogFile" << t.tm_year + 1900 << "." << t.tm_mon + 1 << "." <<
		t.tm_mday << "_" << t.tm_hour << "." << t.tm_min << "." << t.tm_sec << ".txt";
	cout << "写入的文件为: " << ss.str() << endl;
	return ss.str();
}

// 通过到达时间进行 插入到等到序列进行排序
void insertPCBToWaitingByarrivalTime(PCB* p) {
	/**
	* 按照到达时间的优先级进行排序,到达时间在前的进行在前
	*
	*/

	// 设置状态
	p->state = "Waiting";

	PCB* p1, * p2;
	bool insert = false;
	// 如果 等待队列 为空,或者小于第一个的到达时间,插入到等待队列的第一个
	if (waiting == NULL || p->arrivalTime < waiting->arrivalTime) {
		p->next = waiting;
		waiting = p;
	}
	// 到达时间比第一个大, 在第一个的后面 查找
	else {
		p1 = waiting;
		p2 = p1->next;
		while (p2 != NULL) {
			if (p->arrivalTime < p2->arrivalTime) {
				// 在两个中间, 插入到第一个和第二个的中间
				p->next = p2;
				p1->next = p;
				p2 = NULL;   // 说明已经找到位置
				insert = true;
			}
			else {
				// 指针向下移动
				p1 = p1->next;
				p2 = p2->next;
			}
		}
		if (insert == false) {
			// 此时说明没有只有头部节点,只能插入到它的后面 此时 p2 == NULL
			p1->next = p;
		}
	}
}


// 将满足到达的进程根据不同的要求插入到Ready队列中
void insertFromWaitingToReady(void (*func)(PCB *p)) {
	PCB* p;
	if (waiting != NULL) {
		// 当开始的第一个到达时间满足的时候
		while (waiting != NULL && waiting->arrivalTime <= TIME) {

			p = waiting;
			//			cout << "进程: " << p->ID << "insertP" << "时间满足条件" << (p->arrivalTime <= time) << endl;
			p->state = "Ready";
			waiting = waiting->next;
			func(p);
		}
		if (waiting != NULL) {
			// 第一个条件不能满足的时候
			PCB* p1 = waiting;
			PCB* p2 = p1->next;
			while (p1 != NULL && p2 != NULL) {
				if (p2->arrivalTime <= TIME) {
					// 修改状态
					PCB* insert_p = p2;
					insert_p->state = "Ready";
					// 移动指针
					if (p2->next != NULL) {

						p1->next = p2->next;
						p2 = p1->next;
						insert_p->next = NULL;
						func(insert_p);
					}
					else {
						// p2刚好是最后满足条件的
						p1->next = NULL;  // 释放连接
						p2->next = NULL;
						func(p2);
						break;
					}


				}
				else {
					// 向下移动
					p1 = p1->next;
					p2 = p2->next;
				}
			}
		}
	}
}

// 输入信息
void inputPCB() {

	// 手动输入进程
	/**
	* 输入数据到链表中
	* 按照一定的格式输入
	*/
	cout << "\t\t输入进程的数目: " << endl << "\t\t";
	fout << "\t\t输入进程的数目: " << endl << "\t\t";
	int NUM;
	cin >> NUM;
	fout << NUM << endl;
	for (int i = 0; i < NUM; ++i) {
		SEEK = i;
		//		cout << "\t输入第" << i + 1 << "个进程" << endl;



		PCB* p = new PCB();
		cin >> *p;
		//		fout << *p;
		insertPCBToWaitingByarrivalTime(p);
	}

	// 随机产生进程


}


// 每一步都展示PCB信息
void displayPCB(string s) {
	cout << endl;
	cout << endl;
	fout << endl;
	fout << endl;
	cout << "\t\t---------------------------" << s << "--------------------------" << endl;
	fout << "\t\t---------------------------" << s << "--------------------------" << endl;

	PCB* pR = ready, * pRun = running, * pB = blocking, * pW = waiting;
	// 输出正在运行的队列
	cout << "\t\t====================================================" << endl;
	fout << "\t\t====================================================" << endl;

	cout << endl;
	fout << endl;
	cout << "\t\t---------------------正在运行的PCB: -------------------" << endl;
	fout << "\t\t---------------------正在运行的PCB: -------------------" << endl;

	while (pRun != NULL) {
		cout << *pRun << endl;
		fout << *pRun << endl;
		pRun = pRun->next;
	}
	//	cout << "\t\t---------------------正在运行的PCB: -------------------" << endl;

	// 输出ready
	cout << "\t\t---------------------已经就绪的PCB: -------------------" << endl;
	fout << "\t\t---------------------已经就绪的PCB: -------------------" << endl;

	while (pR != NULL) {
		cout << *pR << endl;
		fout << *pR << endl;
		pR = pR->next;
	}

	//	cout << "\t\t---------------------已经就绪的PCB: -------------------" << endl;
	// 输出阻塞队列
	cout << "\t\t---------------------已被阻塞的PCB: -------------------" << endl;
	fout << "\t\t---------------------已被阻塞的PCB: -------------------" << endl;

	while (pB != NULL) {
		cout << *pB << endl;
		fout << *pB << endl;
		pB = pB->next;
	}
	//	cout << "\t\t---------------------已被阻塞的PCB: -------------------" << endl;

	cout << "\t\t---------------------正在等待的PCB: -------------------" << endl;
	fout << "\t\t---------------------正在等待的PCB: -------------------" << endl;

	while (pW != NULL) {
		cout << *pW << endl;
		fout << *pW << endl;
		pW = pW->next;
	}
	//	cout << "\t\t---------------------正在等待的PCB: -------------------" << endl;

	//	cout << "\t\t====================================================" << endl;
//	cout << "\t\t---------------------------" << s << "--------------------------" << endl;
//	fout << "\t\t---------------------------" << s << "--------------------------" << endl;
	cout << endl;
	cout << endl;
	fout << endl;
	fout << endl;
}


// 只有完成的时候才进行展示完成的PCB信息
void displayFinishPCB() {
	PCB* p = finish;
	cout << "\t---------------finish------------" << endl;
	fout << "\t---------------finish------------" << endl;
	while (p != NULL) {
		cout << *p << endl;
		fout << *p << endl;
		p = p->next;
	}
	cout << "\t---------------finish------------" << endl;
	fout << "\t---------------finish------------" << endl;

}



// 进程完成
void destroyPCB() {
	/**
	* 将完成的PCB插入到队列首
	*/
	if (running != NULL) {

		cout << "\t\t******* " << running->ID << " 运行完成 ****" << endl << endl;
		fout << "\t\t******* " << running->ID << " 运行完成 ****" << endl << endl;

		running->state = "Finish";
		// 前插入到完成队列

		running->next = finish;
		finish = running;
		// 运行队列置空

		running = NULL;
		// 展示已经完成的 PCB
//		displayFinishPCB();
	}

}


动态最大优先数优先的调度算法

调度原则:

  • 进程的优先数及需要的运行时间可以事先人为地指定,进程的到达时间为进程输入的时间
  • 进程的运行时间以时间片为单位进行计算
  • 进程在就绪队列中带一个时间片,优先数加1
  • 每个进程的状态可以是就绪R(Ready)、运行N(Run)、阻塞B(Block)、或完成F(Finish)四种状态之一
  • 就绪进程获得CPU后都只能运行一个时间片,用已占用CPU时间加1来表示
  • 如果运行一个时间片后,进程的已占用CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减3,然后把它插入就绪队列等待CPU
  • 每进行一次调度程序都打印一次运行进程、就绪队列、以及各个进程的PCB,以便进行检查
  • 重复以上过程,直到所要进程都完成为止
// ===============动态优先级调度算法===============
void insertAndSortPCBToReadyByPriorityOFDP(PCB* p);   // 按照优先级的先后插入到ready队列
void runPCBOfDP();                             // 从 ready 中取出 PCB 运行
void wakeupPCBByPriorityOfDP();				// 唤醒进程,以优先级插入到ready
void DP();	    // 处理函数

// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<动态优先级调度 <<<<<<<<<<<<<<<<<<<<<<<<<<
// 通过优先级插入
void insertAndSortPCBToReadyByPriorityOFDP(PCB* p) {
	/**
	* 排序插入PCB队列
	* 1. 比链表的第一个大的时候,或者首队列是空队列,此时 新PCB 插入到队列首
	* 2. 如果 新PCB 的在链表的中间,则使用两个指针进行移动
	* 3. 注意插入的时候,如果只有一个节点且优先级最高,则直接插入到它的后面,用没有插入 insert进行标记
	*/
	PCB* first, * second;
	bool insert = false; // 是否插入

	// 如果就绪队列为空,或者优先级高于队列首元素,则插入到队列首
	if ((ready == NULL) || (p->priority > ready->priority)) {
		p->next = ready;
		ready = p;
	}
	// 要插入的PCB 优先级 比首PCB小的时候
	else {
		first = ready;
		second = first->next;
		// 循环插入到两个进程之间
		while (second != NULL) {
			// 如果在第一个和第二个之间
			if (p->priority >= second->priority) {
				p->next = second;
				first->next = p;
				second = NULL;
				insert = true;
			}
			else {
				first = first->next;
				second = second->next;
			}
		}

		// 表示没有插入到first与second之间
		// 此时直接插入到第一个的后面, 说明说明链表的头部只有一个节点,且优先级高
		if (!insert) {
			first->next = p;
			p->next = NULL;
		}
	}

}

// 运行处理进程函数
void runPCBOfDP() {

	/**
	* 步骤:
	* 1. 每一次从不为空的 ready 队列中 取出第一个作为处理进程
	* 2. 当有进程可以处理的时候,工作时间加 1 个时间片,优先级 加 固定的优先级
			 1). 当达到完成时间的时候,进程退出
			 2). 当使用一定的时间片后,进程自己阻塞
			 3). 都没有满足的时候,再次插入到就绪队列
			 无论是退出、阻塞、再次就绪, running 都设置为空
	*/

	// 如果没有运行的进程,从就绪进程中选取
	if (running == NULL) {
		if (ready != NULL) {
			// 取出第一个进程
			running = ready;
			ready = ready->next;

			running->state = "Running";
			running->next = NULL;
			// 就绪队列前进
		}
	}
	bool runningFlag = false;

	if (running != NULL) {
		runningFlag = true;
		// 进程运行的时间增加
		running->CPUTime++;
		// 进程优先级加1
		running->allTime--;
		running->priority += ADD_PRIORITY;
		// 展示运行的状态
		displayPCB("运行......");
		if (running->allTime <= 0) {
			destroyPCB();
		}
		else {
			// 进程运行要阻塞的时间 加 1
			running->startBlock += TIME_LIMIT;

			if (running->startBlock >= BLOCK_NUM) {

				// 修改状态, 插入到队列首,无需排序
				running->state = "Block";
				running->startBlock = 0;
				running->blockCount++;
				// 加入到block队列的头部

				running->next = blocking;
				blocking = running;
				running = NULL;

			}
			else {
				// 优先级降低
				running->priority -= SUB_PRIORITY;
				// 修改状态
				running->state = "Ready";

				PCB* p = running;
				p->next = NULL;
				insertAndSortPCBToReadyByPriorityOFDP(p);
				// 将running进程插入到就绪队列后,running队列为空
				running = NULL;
			}
		}
	}
	if (!runningFlag && waiting != NULL) {
		displayPCBOfWaiting();
	}
	if (!runningFlag && blocking != NULL) {
		// 当有队列被阻塞的时候,进行唤醒
		displayPCBOfBlock();
	}
	wakeupPCBByPriorityOfDP();  // 每次唤醒
}


void wakeupPCBByPriorityOfDP() {

	/**
	* 唤醒的步骤
	* 1. 当blocking队列不为空的时候进行唤醒
	* 2. 检查链表首节点是否都满足,满足则插入到就绪队列
	* 3. 当第一个节点不满足的时候,检查第二个节点,保留前一个,用链表遍历的思想
	*/

	if (blocking != NULL) {

		PCB* p = blocking;
		while (p != NULL) {
			p->startTime++;
			p = p->next;
		}

		// 如何唤醒阻塞的进程
		/**
		* 第一个进程全部满足条件 能被唤醒
		*/
		while (blocking != NULL && blocking->startTime >= START_NUM) {
			p = blocking;
			blocking = blocking->next;
			p->startTime = 0;
			p->wakeupCount++;
			// 最后修改指针
			p->next = NULL;
			insertAndSortPCBToReadyByPriorityOFDP(p);
		}

		/**
		* 不是第一个的 唤醒
		*/
		if (blocking != NULL) {
			PCB* p1 = blocking;
			PCB* p2 = p1->next;
			while (p2 != NULL && p1 != NULL) {
				if (p2->startTime >= START_NUM) {
					PCB* i_p = p2;
					i_p->startTime = 0;
					i_p->wakeupCount++;

					// 移动指针
					p1->next = p2->next;
					p2 = p1->next;

					insertAndSortPCBToReadyByPriorityOFDP(i_p);
				}

				else {
					p1 = p1->next;
					p2 = p2->next;
				}

			}
		}
	}
}

void DP() {

	string t = getFileName("DB_algo_");
	fout.open(t.c_str());

	char c;
	inputPCB();
	displayPCB("输入的PCB");
	cout << endl << endl;
	fout << endl << endl;
	while (ready != NULL || running != NULL || blocking != NULL || waiting != NULL) {
		TIME += 1;
		cout << "\t\t运行的时间 : " << TIME << endl;
		fout << "\t\t运行的时间 : " << TIME << endl;
		//		c = getchar();
		insertFromWaitingToReady(insertAndSortPCBToReadyByPriorityOFDP);
		runPCBOfDP();
	}
	displayPCB("最后信息");
	displayFinishPCB();

	fout.close();
}


先来先服务算法

// 先来先服务调度算法
void insertAndSortToReadyByArrivalTimeOfFCFS(PCB* p);   // 插入到ready队列 按照到达时间进行排序
void runPCBOfFCFS();    // 从ready中取出一个处理
void FCFS();		 // 主处理函数


// >>>>>>>>>>>>>>>>>>>>>>>先来先服务算法<<<<<<<<<<<<<<<<<<<<<<<

// 按照先到时间的优先级插入
void insertAndSortToReadyByArrivalTimeOfFCFS(PCB* p) {
	// 将到达时间的进程放到ready的后面
	if (ready == NULL) {
		ready = p;
		ready->next = NULL;
	}
	else {
		PCB* pT = ready;
		while (pT->next != NULL) {
			pT = pT->next;
		}
		pT->next = p;
		p->next = NULL;
	}
}
// 先来先服务算法
void runPCBOfFCFS() {
	/**
	* 第一个到达的先服务,服务完毕后结束
	*/
	if (running == NULL) {
		if (ready != NULL) {
			running = ready;
			ready = ready->next;
			running->state = "Running";
			running->next = NULL;
		}
	}
	bool runningFlag = false;
	if (running != NULL) {


		runningFlag = true;
		running->CPUTime++;
		running->allTime--;

		displayPCB("Running");

		if (running->allTime <= 0) {
			destroyPCB();
		}
	}

	if (!runningFlag && waiting != NULL) {
		displayPCBOfWaiting();
	}


}
// 算法主体
void FCFS() {
	// char c;
	string t = getFileName("FCFS_algo_");
	fout.open(t.c_str());

	inputPCB();
	displayPCB("输入的PCB");
	cout << endl << endl;
	fout << endl << endl;
	while (ready != NULL || running != NULL || blocking != NULL || waiting != NULL) {
		TIME += 1;
		cout << "\t\t运行的时间 : " << TIME << endl;
		fout << "\t\t运行的时间 : " << TIME << endl;
		//		c = getchar();
		insertFromWaitingToReady(insertAndSortToReadyByArrivalTimeOfFCFS);
		runPCBOfFCFS();
	}
	displayPCB("最后信息");
	displayFinishPCB();
	fout.close();
}



短进程优先算法

// 短进程优先
void insertAndSortToReadyByMinAllTimeOfSPF(PCB* p);   // 插入到ready队列 按照总运行时间最低
void runPCBOfSPF();                       // 从  ready  中取出PCB进行处理
void SPF();


// >>>>>>>>>>>>>>>>>>>>>>>>>> 短进程优先算法 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// 到达时间后插入到ready时进行 按总运行大小 排序
void insertAndSortToReadyByMinAllTimeOfSPF(PCB* p) {
	PCB* p1, * p2;
	bool insert;
	// 第一个ready PCB为空的时候, 或者是 更短的进程, 插入前面
	if ((ready == NULL) || (p->allTime <= ready->allTime)) {
		p->next = ready;
		ready = p;
	}
	else {
		// 说明没有插入到第一个, 在第一个与第二个之间查找
		p1 = ready;
		p2 = p1->next;
		insert = false;

		while (p2 != NULL) {
			if (p->allTime <= p2->allTime) {
				// 此时插入到p1 与 p2 之间
				p1->next = p;
				p->next = p2;
				//				p2 = NULL;    // 已经插入,结束的条件
				insert = true;
				break;
			}
			else {
				p1 = p1->next;
				p2 = p2->next;
			}
		}
		if (!insert) {
			// 此时小于第一个 没有第二个, 插入第一个的后面
			ready->next = p;
			p->next = NULL;
		}
	}

}


void runPCBOfSPF() {
	// 取出ready的第一个PCB,已经排好序的 最短进程
	if (running == NULL) {
		if (ready != NULL) {
			running = ready;
			ready = ready->next;
			running->state = "Running";
			running->next = NULL;
		}
	}

	bool runningFlag = false;

	if (running != NULL) {
		runningFlag = true;
		// 对于正在运行的进程进行处理

		running->CPUTime++;
		running->allTime--;

		displayPCB("Running");

		//

		if (running->allTime <= 0) {

			destroyPCB();
		}
	}

	if (!runningFlag && waiting != NULL) {
		displayPCBOfWaiting();
	}
}

void SPF() {
	// 输入之前打开文件
	string t = getFileName("SPF_algo_");
	fout.open(t.c_str());

	inputPCB();
	displayPCB("输入的PCB");
	cout << endl << endl;
	fout << endl << endl;
	while (ready != NULL || running != NULL || blocking != NULL || waiting != NULL) {
		TIME += 1;
		cout << "\t\t运行的时间 : " << TIME << endl;
		fout << "\t\t运行的时间 : " << TIME << endl;
		insertFromWaitingToReady(insertAndSortToReadyByMinAllTimeOfSPF);
		runPCBOfSPF();
	}
	displayPCB("最后信息");
	displayFinishPCB();

	fout.close();
}


时间片轮转调度算法

// >>>>>>>>>>>>>>>>>>>>>>>>>>  时间片轮转调度算法 >>>>>>>>>>>>>>>>>>
// 插入原则 按进程到达的顺序进行
void insertAndSortToReadyByFCFSOfTimeLimit(PCB* p) {
	// 将到达时间的进程放到ready的后面
	if (ready == NULL) {
		ready = p;
		ready->next = NULL;
	}
	else {
		PCB* pT = ready;
		while (pT->next != NULL) {
			pT = pT->next;
		}
		pT->next = p;
		p->next = NULL;
	}
}

void wakeupPCBByFCFSOfTimeLimit() {

	/**
	* 唤醒的步骤
	* 1. 当blocking队列不为空的时候进行唤醒
	* 2. 检查链表首节点是否都满足,满足则插入到就绪队列
	* 3. 当第一个节点不满足的时候,检查第二个节点,保留前一个,用链表遍历的思想
	*/

	if (blocking != NULL) {

		PCB* p = blocking;
		while (p != NULL) {
			p->startTime++;
			p = p->next;
		}

		// 如何唤醒阻塞的进程
		/**
		* 第一个进程全部满足条件 能被唤醒
		*/
		while (blocking != NULL && blocking->startTime >= START_NUM) {
			p = blocking;
			blocking = blocking->next;
			p->startTime = 0;
			p->wakeupCount++;  // 唤醒次数加一
			insertAndSortToReadyByFCFSOfTimeLimit(p);
		}

		/**
		* 第一个进程不能唤醒的时候, 唤醒后面的进程
		*/
		if (blocking != NULL) {
			PCB* p1 = blocking;
			PCB* p2 = p1->next;
			while (p2 != NULL && p1 != NULL) {
				if (p2->startTime >= START_NUM) {
					p2->startTime = 0;
					p1->next = p2->next;    
					p2->wakeupCount++;
					
					insertAndSortToReadyByFCFSOfTimeLimit(p2);

					p2 = p1->next; // p2指向下一个, 以便于循环继续
				}

				else {
					p1 = p1->next;
					p2 = p2->next;
				}

			}
		}
	}
}

void runPCBOfTimeLimit() {
	// 取出第一个进程进行处理
	if (running == NULL) {
		if (ready != NULL) {
			running = ready;
			ready = ready->next;
			running->state = "Running";
			running->next = NULL;      // 只有一个进程在处理机
		}
	}

	bool runningFlag = false;

	if (running != NULL) {

		runningFlag = true;

		running->CPUTime++;
		running->allTime--;

		displayPCB("TimeLimit Running");
		if (running->allTime <= 0) {
			destroyPCB();  // 结束 running的进程
		}
		else {
			running->startBlock += TIME_LIMIT;
			if (running->startBlock >= BLOCK_NUM) {
				// 修改状态
				running->state = "Block";
				running->blockCount++;
				running->startBlock = 0;
				// 插入到队列的首
				running->next = blocking;
				blocking = running;
				running = NULL;   // 删除运行的进程
			}
		}
	}
	if (!runningFlag && waiting != NULL) {
		displayPCBOfWaiting();
	}
	if (!runningFlag && blocking != NULL) {
		// 当有队列被阻塞的时候,进行唤醒
		displayPCBOfBlock();
		wakeupPCBByFCFSOfTimeLimit();
	}
}

void TimeLimit() {
	char c;

	// 输入之前打开文件
	string t = getFileName("TimeLimit_algo_");
	fout.open(t.c_str());

	inputPCB();
	displayPCB("输入的PCB");
	cout << endl << endl;
	fout << endl << endl;

	while (ready != NULL || running != NULL || blocking != NULL || waiting != NULL) {
		TIME += 1;
		cout << "\t\t运行的时间 : " << TIME << endl;
		fout << "\t\t运行的时间 : " << TIME << endl;
		//		c = getchar();
		insertFromWaitingToReady(insertAndSortToReadyByFCFSOfTimeLimit);
		runPCBOfTimeLimit();
	}

	displayPCB("最后信息");
	displayFinishPCB();

	fout.close();

}


执行

int main() {
	//		DP();
	//		FCFS();
	//		SPF();
	TimeLimit();
	return 0;
}
  • 4
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值