操作系统进程调度算法 C++

使用C和C++实现的简单的操作系统进程调度算法

1.使用的数据结构

//PCB数据结构 
struct PCB{
	long id;
	int priority=1;
	long start;
	long runtime; 
	long usedtime; 
	long end; 
	void create(long i,long st,long rt){
		id=i;
		start=st;
		runtime=rt;
	}
	void selected(long now){
		printf("(%02d:%02d) select process %d,need:%-3d,used:%-3d\n",now/60,now%60,id,runtime,usedtime);
	}
	void run(long now){
		//printf("(%02d:%02d) process %d run,need:%-3d,used:%-3d++\n",now/60,now%60,id,runtime,usedtime);
		usedtime++;
	}
}P[10010];

2.构造测试用例

//构建测试用例
map<long,long> mp;
void initPCS(){
	//默认
	long start[6]={0,8*60,8*60+20,8*60+25,8*60+30,8*60+35};
	long runtimes[6]={0,25,10,20,20,15};
	memset(P,0,5*sizeof(PCB)); 
	for(long id=1;id<=5;id++){
		P[id].create(id,start[id],runtimes[id]);
		mp[ start[id] ]=id;
	}
}

3.先来先服务

3.1流程

3.2代码实现

//FCFS算法
void FCFS(){
	long now=8*60;//定义初始时间 08:00
	const long end=12*60;//定义终止时间 12:00
	
	queue<int> wait;//等待队列
	long id;//运行进程的ID
	bool status=0;//运行进程的状态(0:结束)
	
	if(mp.find(now)!=mp.end()){//有进程创建 
		long id=mp[now];
		wait.push(id);//放入wait队列 
	}
	while(now<end){
		if(status){//进程尚未运行结束 
			P[id].run(now); 
			now++;
			if(mp.find(now)!=mp.end()){//有进程创建
				wait.push(mp[now]);//放入wait队列
			}
			if(P[id].runtime==P[id].usedtime){//运行结束 
				P[id].end=now;
				status=0;//运行状态修改为:运行结束 
			}
			continue;
		}
		if(wait.size()!=0){
			id=wait.front();//选出先来的(队头)
			wait.pop();
			status=1;//运行状态修改为:运行中
			P[id].selected(now);//打印日志 
		}else{
			now++;
			if(mp.find(now)!=mp.end()){//有进程创建
				wait.push(mp[now]);//放入wait队列
			}
			continue;
		}
	}
}

3.3运行结果

4.短作业优先算法

4.1流程

短作业优先与先来先服务唯一的不同在于:短作业优先在选择作业时需要去作业中寻找最短者

4.2代码实现

//SJF算法(非抢占式)
void SJF(){
	long now=8*60;//定义初始时间
	const long end=12*60;//定义终止时间 
	
	long id;//运行进程的ID 
	vector<int> wait;//等待队列
	bool status=0;//运行进程的状态(0:结束)
	
	if(mp.find(now)!=mp.end()){//有进程创建 
		wait.push_back(mp[now]);//放入wait队列 
	}
	while(now<end){
		if(status){//进程尚未运行结束 
			P[id].run(now); 
			now++;
			if(mp.find(now)!=mp.end()){//有进程创建
				wait.push_back(mp[now]);//放入wait队列
			}
			if(P[id].runtime==P[id].usedtime){//运行结束 
				P[id].end=now;
				status=0;//运行状态修改为:运行结束 
			}
			continue;
		}
		if(wait.size()!=0){
			
			//找到最短的进程 
			long surplus=(1<<16);
			int itmp;
			for(int i=0;i<wait.size();i++){
				long s=P[ wait[i] ].runtime;
				if(s<surplus){
					surplus=s;
					itmp=i;
				}
			}
			id=wait[itmp];
			wait.erase(wait.begin()+itmp);
			
			status=1;//运行状态修改为:运行中
			P[id].selected(now);//打印日志 
		}else{
			now++;
			if(mp.find(now)!=mp.end()){//有进程创建
				wait.push_back(mp[now]);//放入wait队列
			}
			continue;
		}
	}
}

4.3运行结果

5高相应比优先算法

5.1代码实现

void HRRN(){
	long now=8*60;//定义初始时间
	const long end=12*60;//定义终止时间 
	
	long id;//运行进程的ID
	vector<int> wait;//等待队列
	bool status=0;//运行进程的状态(0:结束)
	
	if(mp.find(now)!=mp.end()){//有进程创建 
		wait.push_back(mp[now]);//放入wait队列 
	}
	while(now<end){
		if(status){//进程尚未运行结束 
			P[id].run(now); 
			now++;
			if(mp.find(now)!=mp.end()){//有进程创建
				wait.push_back(mp[now]);//放入wait队列
			}
			if(P[id].runtime==P[id].usedtime){//运行结束 
				P[id].end=now;
				status=0;//运行状态修改为:运行结束 
			}
			continue;
		}
		if(wait.size()!=0){
			
			//找到高响应比的进程
			double surplus=0;
			int itmp;
			for(int i=0;i<wait.size();i++){
				double s=1+((now-P[ wait[i] ].start)-P[ wait[i] ].usedtime)*1.0/P[ wait[i] ].runtime;//相应比=1+等待时间/要求服务时间 
				if(s>surplus){
					surplus=s;
					itmp=i;
				}
			}
			id=wait[itmp];
			wait.erase(wait.begin()+itmp);
			
			status=1;//运行状态修改为:运行中
			P[id].selected(now);//打印日志 
		}else{
			now++;
			if(mp.find(now)!=mp.end()){//有进程创建
				wait.push_back(mp[now]);//放入wait队列
			}
			continue;
		}
	}
}

 5.2运行结果

6.轮转算法

6.1流程

轮转算法是在FCFS的基础上加上了时间片的限制

 6.2代码实现

//RR算法 
void RR(){
	long now=8*60;//定义初始时间 08:00
	const long end=12*60;//定义终止时间 12:00
	const long dt=10;//时间片长度
	
	queue<int> wait;//等待队列
	long id;//运行进程的ID 
	 
	if(mp.find(now)!=mp.end()){//有进程创建 
		long id=mp[now];
		wait.push(id);//放入wait队列 
	}
	while(now<end){
		if(wait.size()==0){//等待队列为空 
			//cout<<"jump"<<endl;
			now++;
			if(mp.find(now)!=mp.end()){//有进程创建 
				wait.push(mp[now]);//放入wait队列
			}
			continue;
		}
			
		id=wait.front();//选出先来的(队头) 
		wait.pop();
		P[id].selected(now); 
		for(long i=0;i<dt;i++){
			P[id].run(now++);
			if(mp.find(now)!=mp.end()){//有进程创建 
				wait.push(mp[now]);//放入wait队列
			}
			if(P[id].runtime!=P[id].usedtime){//运行未结束 
				//wait.push(id);
			}else{//运行结束 
				P[id].end=now;
				break;	
			}
		}
		if(P[id].runtime!=P[id].usedtime){//运行未结束 
			wait.push(id);
		}
	}
}

6.3运行结果

7.抢占式SJF

7.1流程

7.2代码实现

//SJF算法(抢占式)
void SJF2(){
	long now=8*60;//定义初始时间
	const long end=12*60;//定义终止时间 
	
	long id;//运行进程的ID
	vector<int> wait;//等待队列
	bool status=0;//运行进程的状态(0:结束)
	
	if(mp.find(now)!=mp.end()){//有进程创建 
		wait.push_back(mp[now]);//放入wait队列 
	}
	while(now<end){
		if(status){//进程尚未运行结束 
			P[id].run(now); 
			now++;
			if(mp.find(now)!=mp.end()){//有进程创建
				wait.push_back(mp[now]);//放入wait队列
				status=0;//当前进程终止运行 
				if(P[id].runtime!=P[id].usedtime)
					wait.push_back(id);//当前进程放入wait队列
			}
			if(P[id].runtime==P[id].usedtime){//运行结束 
				P[id].end=now;
				status=0;//运行状态修改为:运行结束 
			}
			continue;
		}
		if(wait.size()!=0){
			//找到最短的进程 
			long surplus=(1<<16);
			int itmp;
			for(int i=0;i<wait.size();i++){
				long s=P[ wait[i] ].runtime-P[ wait[i] ].usedtime;
				if(s<surplus){
					surplus=s;
					itmp=i;
				}
			}
			id=wait[itmp];
			wait.erase(wait.begin()+itmp);
			
			status=1;//运行状态修改为:运行中
			P[id].selected(now);//打印日志 
		}else{
			now++;
			if(mp.find(now)!=mp.end()){//有进程创建
				wait.push_back(mp[now]);//放入wait队列
			}
			continue;
		}
	}
}

 7.3运行结果

8.数据打印方法

//数据统计
void cacu_data(int n){
	double sumt1=0;
	double sumt2=0;
	printf("---------------------------------------------------\n"); 
	printf("%2s|%8s|%8s|%8s|%8s|%12s\n","ID","到达时间","运行时间",
			"完成时间","周转时间","带权周转时间");
	for(int i=1;i<=n;i++){
		printf("%-2d|(%02d:%02d) |%-4d min|(%02d:%02d) |%-4d min|%-4lf\n",P[i].id,
			P[i].start/60,P[i].start%60,P[i].runtime,P[i].end/60,P[i].end%60,
			P[i].end-P[i].start,(P[i].end-P[i].start)*1.0/P[i].runtime);
		
		sumt1+=P[i].end-P[i].start;
		sumt2+=(P[i].end-P[i].start)*1.0/P[i].runtime;
	}
	cout<<"平均周转时间:"<<sumt1/n<<endl;
	cout<<"平均带权周转时间:"<<sumt2/n<<endl;
}

9.完整代码

#include<iostream>
#include<stdio.h>
#include<queue>
#include<vector>
#include<cstring>
#include<map>
using namespace std;

//PCB数据结构 
struct PCB{
	long id;
	int priority=1;
	long start;
	long runtime; 
	long usedtime; 
	long end; 
	void create(long i,long st,long rt){
		id=i;
		start=st;
		runtime=rt;
	}
	void selected(long now){
		printf("(%02d:%02d) select process %d,need:%-3d,used:%-3d\n",now/60,now%60,id,runtime,usedtime);
	}
	void run(long now){
		//printf("(%02d:%02d) process %d run,need:%-3d,used:%-3d++\n",now/60,now%60,id,runtime,usedtime);
		usedtime++;
	}
}P[10010];
map<long,long> mp;
//构建测试用例
void initPCS(){
	//默认
	long start[6]={0,8*60,8*60+20,8*60+25,8*60+30,8*60+35};
	long runtimes[6]={0,25,10,20,20,15};
	memset(P,0,5*sizeof(PCB)); 
	for(long id=1;id<=5;id++){
		P[id].create(id,start[id],runtimes[id]);
		mp[ start[id] ]=id;
	}
}
//FCFS算法
void FCFS(){
	long now=8*60;//定义初始时间 08:00
	const long end=12*60;//定义终止时间 12:00
	
	queue<int> wait;//等待队列
	long id;//运行进程的ID
	bool status=0;//运行进程的状态(0:结束)
	
	if(mp.find(now)!=mp.end()){//有进程创建 
		long id=mp[now];
		wait.push(id);//放入wait队列 
	}
	while(now<end){
		if(status){//进程尚未运行结束 
			P[id].run(now); 
			now++;
			if(mp.find(now)!=mp.end()){//有进程创建
				wait.push(mp[now]);//放入wait队列
			}
			if(P[id].runtime==P[id].usedtime){//运行结束 
				P[id].end=now;
				status=0;//运行状态修改为:运行结束 
			}
			continue;
		}
		if(wait.size()!=0){
			id=wait.front();//选出先来的(队头)
			wait.pop();
			status=1;//运行状态修改为:运行中
			P[id].selected(now);//打印日志 
		}else{
			now++;
			if(mp.find(now)!=mp.end()){//有进程创建
				wait.push(mp[now]);//放入wait队列
			}
			continue;
		}
	}
}
//SJF算法(非抢占式)
void SJF(){
	long now=8*60;//定义初始时间
	const long end=12*60;//定义终止时间 
	
	long id;//运行进程的ID 
	vector<int> wait;//等待队列
	bool status=0;//运行进程的状态(0:结束)
	
	if(mp.find(now)!=mp.end()){//有进程创建 
		wait.push_back(mp[now]);//放入wait队列 
	}
	while(now<end){
		if(status){//进程尚未运行结束 
			P[id].run(now); 
			now++;
			if(mp.find(now)!=mp.end()){//有进程创建
				wait.push_back(mp[now]);//放入wait队列
			}
			if(P[id].runtime==P[id].usedtime){//运行结束 
				P[id].end=now;
				status=0;//运行状态修改为:运行结束 
			}
			continue;
		}
		if(wait.size()!=0){
			
			//找到最短的进程 
			long surplus=(1<<16);
			int itmp;
			for(int i=0;i<wait.size();i++){
				long s=P[ wait[i] ].runtime;
				if(s<surplus){
					surplus=s;
					itmp=i;
				}
			}
			id=wait[itmp];
			wait.erase(wait.begin()+itmp);
			
			status=1;//运行状态修改为:运行中
			P[id].selected(now);//打印日志 
		}else{
			now++;
			if(mp.find(now)!=mp.end()){//有进程创建
				wait.push_back(mp[now]);//放入wait队列
			}
			continue;
		}
	}
}
//SJF算法(抢占式)
void SJF2(){
	long now=8*60;//定义初始时间
	const long end=12*60;//定义终止时间 
	
	long id;//运行进程的ID
	vector<int> wait;//等待队列
	bool status=0;//运行进程的状态(0:结束)
	
	if(mp.find(now)!=mp.end()){//有进程创建 
		wait.push_back(mp[now]);//放入wait队列 
	}
	while(now<end){
		if(status){//进程尚未运行结束 
			P[id].run(now); 
			now++;
			if(mp.find(now)!=mp.end()){//有进程创建
				wait.push_back(mp[now]);//放入wait队列
				status=0;//当前进程终止运行 
				if(P[id].runtime!=P[id].usedtime)
					wait.push_back(id);//当前进程放入wait队列
			}
			if(P[id].runtime==P[id].usedtime){//运行结束 
				P[id].end=now;
				status=0;//运行状态修改为:运行结束 
			}
			continue;
		}
		if(wait.size()!=0){
			//找到最短的进程 
			long surplus=(1<<16);
			int itmp;
			for(int i=0;i<wait.size();i++){
				long s=P[ wait[i] ].runtime-P[ wait[i] ].usedtime;
				if(s<surplus){
					surplus=s;
					itmp=i;
				}
			}
			id=wait[itmp];
			wait.erase(wait.begin()+itmp);
			
			status=1;//运行状态修改为:运行中
			P[id].selected(now);//打印日志 
		}else{
			now++;
			if(mp.find(now)!=mp.end()){//有进程创建
				wait.push_back(mp[now]);//放入wait队列
			}
			continue;
		}
	}
}
void HRRN(){
	long now=8*60;//定义初始时间
	const long end=12*60;//定义终止时间 
	
	long id;//运行进程的ID
	vector<int> wait;//等待队列
	bool status=0;//运行进程的状态(0:结束)
	
	if(mp.find(now)!=mp.end()){//有进程创建 
		wait.push_back(mp[now]);//放入wait队列 
	}
	while(now<end){
		if(status){//进程尚未运行结束 
			P[id].run(now); 
			now++;
			if(mp.find(now)!=mp.end()){//有进程创建
				wait.push_back(mp[now]);//放入wait队列
			}
			if(P[id].runtime==P[id].usedtime){//运行结束 
				P[id].end=now;
				status=0;//运行状态修改为:运行结束 
			}
			continue;
		}
		if(wait.size()!=0){
			
			//找到高响应比的进程
			double surplus=0;
			int itmp;
			for(int i=0;i<wait.size();i++){
				double s=1+((now-P[ wait[i] ].start)-P[ wait[i] ].usedtime)*1.0/P[ wait[i] ].runtime;//相应比=1+等待时间/要求服务时间 
				if(s>surplus){
					surplus=s;
					itmp=i;
				}
			}
			id=wait[itmp];
			wait.erase(wait.begin()+itmp);
			
			status=1;//运行状态修改为:运行中
			P[id].selected(now);//打印日志 
		}else{
			now++;
			if(mp.find(now)!=mp.end()){//有进程创建
				wait.push_back(mp[now]);//放入wait队列
			}
			continue;
		}
	}
} 
//RR算法 
void RR(){
	long now=8*60;//定义初始时间 08:00
	const long end=12*60;//定义终止时间 12:00
	const long dt=10;//时间片长度
	
	queue<int> wait;//等待队列
	long id;//运行进程的ID 
	 
	if(mp.find(now)!=mp.end()){//有进程创建 
		long id=mp[now];
		wait.push(id);//放入wait队列 
	}
	while(now<end){
		if(wait.size()==0){//等待队列为空 
			//cout<<"jump"<<endl;
			now++;
			if(mp.find(now)!=mp.end()){//有进程创建 
				wait.push(mp[now]);//放入wait队列
			}
			continue;
		}
			
		id=wait.front();//选出先来的(队头) 
		wait.pop();
		P[id].selected(now); 
		for(long i=0;i<dt;i++){
			P[id].run(now++);
			if(mp.find(now)!=mp.end()){//有进程创建 
				wait.push(mp[now]);//放入wait队列
			}
			if(P[id].runtime!=P[id].usedtime){//运行未结束 
				//wait.push(id);
			}else{//运行结束 
				P[id].end=now;
				break;	
			}
		}
		if(P[id].runtime!=P[id].usedtime){//运行未结束 
			wait.push(id);
		}
	}
}
//数据统计
void cacu_data(int n){
	cout<<endl<<"------初始数据------"<<endl;
	printf("%-2s|%-8s|%-8s\n","ID","到达时间","运行时间");
	for(int i=1;i<=n;i++){
		printf("%-2d|(%02d:%02d) |%-4d min\n",
		P[i].id,
			P[i].start/60,P[i].start%60,P[i].runtime); 
	}
	double sumt1=0;
	double sumt2=0;
	printf("\n----------结果统计---------------------------------\n"); 
	printf("%2s|%8s|%8s|%8s|%8s|%12s\n","ID","到达时间","运行时间",
			"完成时间","周转时间","带权周转时间");
	for(int i=1;i<=n;i++){
		printf("%-2d|(%02d:%02d) |%-4d min|(%02d:%02d) |%-4d min|%-4lf\n",P[i].id,
			P[i].start/60,P[i].start%60,P[i].runtime,P[i].end/60,P[i].end%60,
			P[i].end-P[i].start,(P[i].end-P[i].start)*1.0/P[i].runtime);
		
		sumt1+=P[i].end-P[i].start;
		sumt2+=(P[i].end-P[i].start)*1.0/P[i].runtime;
	}
	cout<<"平均周转时间:"<<sumt1/n<<endl;
	cout<<"平均带权周转时间:"<<sumt2/n<<endl;
}
//主函数 
int main(){
	initPCS();
	//FCFS();//先来先服务 
	//SJF();//短作业优先 
	//SJF2();//抢占式短作业优先 
	//HRRN();//高相应比优先 
	RR();//轮转(时间片默认10分钟)
	
	cacu_data(5);//统计
	return 0;
} 

  • 6
    点赞
  • 58
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
进程调度算法操作系统中非常重要的一部分,用于决定哪些进程将被调度执行。常见的进程调度算法有以下几种: 1. 先来先服务(FCFS)调度算法:按照进程到达的先后顺序进行调度,先到达的进程先执行,后到达的进程后执行。 2. 最短作业优先(SJF)调度算法:按照进程的执行时间进行排序,执行时间短的进程先执行。 3. 优先级调度算法:为每个进程分配一个优先级,根据优先级高低进行调度。 4. 时间片轮转(RR)调度算法:将 CPU 时间分成多个时间片,每个进程执行一个时间片,时间片用完后将进程放到队列尾部,继续执行下一个进程。 下面是一个基于 FCFS 调度算法C++ 代码示例: ```c++ #include <iostream> #include <queue> using namespace std; struct Process { int pid; // 进程 ID int arrive; // 到达时间 int burst; // 执行时间 }; bool operator<(const Process &p1, const Process &p2) { return p1.arrive > p2.arrive; // 按到达时间从小到大排序 } int main() { priority_queue<Process> q; // 优先队列,用于按到达时间排序 int n; // 进程数 cin >> n; for (int i = 0; i < n; i++) { Process p; cin >> p.pid >> p.arrive >> p.burst; q.push(p); } int time = 0; // 当前时间 while (!q.empty()) { Process p = q.top(); q.pop(); time = max(time, p.arrive); // 更新时间,确保当前时间不小于进程的到达时间 time += p.burst; // 执行进程 cout << p.pid << " " << time << endl; // 输出进程 ID 和完成时间 } return 0; } ```
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

li345376

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值