操作系统进程调度---优先级调度算法(抢占模式)

引言

最近学习了操作系统内诸多进程调度算法,动手实现了抢占式优先级调度算法

知识点

该算法又称为优先权调度算法,他既可以用于作业调度,又可用于进程调度。该算法中的优先级用于描述作业运行的紧迫程度。

两种类型:

  1. 非剥夺式(非抢占式)优先级调度算法。当一个进程正在处理上运行时,即使有某个更为重要或紧迫的进程进入就绪队列,仍然让正在进行的进程继续运行,直到由于其自身原因而主动让出处理机(任务完成或等待事件),才把处理机分配给更为重要或紧迫的进程。
  2. 剥夺式(抢占式)优先级调度算法。当一个进程正在处理机上运行时,若有某个更为重要或紧迫的进程进入就绪队列,则立即暂停正在运行的进程,将处理机分配给更重要或紧迫的进程。

两种优先级:

  1. 静态优先级。优先级是在创建进程时确定的,且在进程的整个运行期间保持不变。确定静态优先级的主要依据有进程类型、进程对资源的要求、用户要求。
  2. 动态优先级。在进程运行过程中,根据进程情况的变化动态调整优先级。动态调整优先级的主要依据有进程占有 CPU 时间的长短、就绪进程等待 CPU 时间的长短。

一般来说,进程优先级的设置有下面几点原则:

  1. 系统进程 > 用户进程。系统进程作为系统的管理者,理应拥有更高的优先权。
  2. 交互型进程 > 非交互型进程。与用户进行交互的进程需要被优先处理,即要有更高的优先级。
  3. I/O型进程 > 计算型进程。频繁使用 I/O 设备的进程称为 I/O 型进程,I/O 设备的处理速度要比 CPU慢很多,所以将 I/O 型进程的优先级设置得更高,就有可能让 I/O 设备尽早开始工作,进而提升系统的整体效率。

代码实现(C++)

本程序使用两个栈,分别储存运行进程和进程优先级。
使用栈是为了解决一个进程被另一个进程抢占后的恢复问题,之所以 不用一个栈来存储,是为了避免配有相同优先级但不同进程相遇的情况。

#include<iostream>
#include<string>
#include<windows.h>
#include<stack>		//  用来存储优先权 
#include<list>		//	使用list存储PCB,考虑到无法模拟事件的顺序发生,故不使用队列 

#define MAXNUM 1000 

using namespace std;

typedef struct pcb {
    
    
	int pID;			//	进程编号
	int level;			//	进程优先权
	float needTime;		// 	需要运行时间	 
	float reachTime;	//	到达时间
	float leftTime;		//	剩余运行时间 
}PCB;
	
void createProcess(int n, list<PCB> &plist) {
    
    		//	创建一个进程队列
	cout<<"请输入相应进程的进程编号、优先权、到达时间、运行时间(类似:1 1 0 4)"<<endl;
	
	for(int i=0;i<n;i++) {
    
    
		PCB p;
		cout<<"请输入第"<<i+1<<"个进程的信息:"; 
		cin>>p.pID>>p.level>>p.reachTime>>p.needTime;
		plist.push_front(p);
	}
}	

int getWholeTime(list<PCB> &plist) {
    
    	//	获取所有任务的总时间 
	list<PCB>::iterator i;
	int sumTime = 0;
	
	for(i=plist.begin();i!=plist.end();i++) {
    
    
		sumTime += i->needTime;
	}
	
	return sumTime;
}

void runProcess(int n, list<PCB> &plist) {
    
    		//	运行进程 
	int Clocker = 0;	//	定义一个计时器 
	stack<int> id_stack;	//	定义一个存放进程ID的栈 
	stack<int> level_stack;	//	定义一个存放优先权的栈 
	level_stack.push(0);
	id_stack.push(0);
	int sumTime = getWholeTime(plist); 	//	获取总共运行时间 

	cout<<endl;
	while(Clocker<sumTime) {
    
    
		cout<<"时间片轮转一个单位..."<<endl;
		
		//	遍历找出当前时刻优先权最高的进程 
		list<PCB>::iterator i;
		for(i = plist.begin();i != plist.end();i++) {
    
    
			if(i->reachTime<=Clocker && i->level>=level_stack.top() && i->needTime>0) {
    
    
				if(i->pID != id_stack.top()) {
    
    
					id_stack.push(i->pID);
					level_stack.push(i->level);	
				}
				
				i->needTime--;	//	剩余运行时间减少1个单位 
				if(i->needTime == 0) {
    
    	//	若运行结束,对应优先权出栈 
					level_stack.pop();
					id_stack.pop();
				}
				
				cout<<"本次执行了进程: "<<i->pID<<endl;
				cout<<endl;
				break;
			} 
		}
		
		Sleep(1500);
		Clocker++;	
	}
}
	
/*
	测试用例:
		pID   level   reachTime   needTime
		1		2		  0			 3
		2		4		  2			 1
		3		1		  4			 3
		4		3		  6			 2
*/	
	
int main() {
    
    
	cout<<"请输入进程数量:";
	int n;
	cin>>n;
	
	if(n>MAXNUM) {
    
    		//过热保护 
		cout<<"CPU 即将爆炸,倒计时..."<<endl;
		Sleep(1000);
		cout<<"3..."<<endl;
		Sleep(1000);
		cout<<"2..."<<endl;
		Sleep(1000);
		cout<<"1..."<<endl;
		Sleep(1000);
		cout<<"喵~"<<endl; 
		return 0;
	}
	
	list<PCB> plist;

	createProcess(n,plist);
	runProcess(n,plist);
	
	cout<<"结束!"<<endl; 
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_34533266/article/details/109512979