前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >操作系统实验一进程调度算法模拟_常用的进程调度算法有

操作系统实验一进程调度算法模拟_常用的进程调度算法有

作者头像
全栈程序员站长
发布2022-09-27 11:32:34
1.6K0
发布2022-09-27 11:32:34
举报
文章被收录于专栏:全栈程序员必看

大家好,又见面了,我是你们的朋友全栈君。

今日闲来无聊,发现很早之前写的操作系统实验还没有整理,再加上有很多人问,索性就发成博客吧。

实验一 进程调度算法 一、实验目的   用高级语言编写和调试一个进程调度程序,以加深对进程的概念及进程调度算法的理解. 二、实验指导 设计一个有 N个进程共行的进程调度程序。   进程调度算法:分别采用先来先服务算法、短作业优先算法、高响应比优先算法实现。   每个进程用一个进程控制块( PCB)表示。进程控制块可以包含如下信息:进程名、优先级、到达时间、要求服务时间、进程状态等等。 其中到达时间和要求服务时间可以在程序中进行初始化或者在程序开始时由键盘输入。   每个进程的状态可以是就绪 W(Wait)、运行R(Run)、或完成F(Finish)三种状态之一。   每个进程完成后要打印该作业的开始运行时刻、完成时刻、周转时间和带权周转时间,这一组进程完成后要计算并打印这组进程的平均周转时间、带权平均周转时间。 三、提示 1、在采用短作业优先算法和高响应比优先算法进行调度时应注意进程的到达时间,对于没有到达的进程不应参与调度。 2、注意在采用高响应比优先算法时计算优先权的时机,因为采用动态优先权,所以应在每次调度之前都重新计算优先权,高响应比优先算法采用下列公式计算优先权

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

进程调度算法流程图

代码语言:javascript
复制
#include<bits/stdc++.h>
#include<windows.h>
using namespace std;
struct PCB
{ 
   
	string name;
	int arrive_time;
	int service_time;
	int exit_time;
	int wait_time;
	double quan;
	bool ifrun;
	int RR_time;
} pcb[10];
queue<PCB> q;
PCB Que[100];
PCB MQ[50][50];
PCB fcfs[10];
PCB sjf[10];
PCB hrrn[10];
PCB rr[10];
PCB mfq[10];
int top=0;
bool cmpSJF(PCB a,PCB b)
{ 
   
	return a.service_time<b.service_time;
}

bool cmpHRRN(PCB a,PCB b)
{ 
   
	return a.quan>b.quan;
}
void menu()
{ 
   
	printf("进程调度模拟程序\n\n");
	printf("1. 输入作业情况\n\n");
	printf("2. 显示作业情况\n\n");
	printf("3. 先来先服务算法\n\n");
	printf("4. 短作业优先算法\n\n");
	printf("5. 高响应比优先算法\n\n");
	printf("6. 时间片轮转算法\n\n");
	printf("7. 多级反馈队列调度\n\n");
	printf("8. 算法结果对比\n\n");
	printf("0. 退出\n\n");
}
void init()
{ 
   
	pcb[0]= { 
   "A",0,3,0,0,0,false,0};
	pcb[1]= { 
   "B",2,6,0,0,0,false,0};
	pcb[2]= { 
   "C",4,4,0,0,0,false,0};
	pcb[3]= { 
   "D",6,5,0,0,0,false,0};
	pcb[4]= { 
   "E",8,2,0,0,0,false,0};
}
void input()
{ 
   
	for(int i=0; i<5; i++)
	{ 
   
		printf("进程%d:\n",i);
		printf("请输入进程名称:");
		cin>>pcb[i].name;
		printf("请输入到达时间:");
		cin>>pcb[i].arrive_time;
		printf("请输入服务时间:");
		cin>>pcb[i].service_time;
		printf("\n");
	}
}
void display()
{ 
   
	printf("名称");
	printf(" ");
	for(int i=0; i<=4; i++)
		cout<<pcb[i].name<<" ";
	printf("\n到达时间 ");
	for(int i=0; i<=4; i++)
		cout<<pcb[i].arrive_time<<" ";
	printf("\n服务时间 ");
	for(int i=0; i<=4; i++)
		cout<<pcb[i].service_time<<" ";
	printf("\n");
	system("pause");
}

void output(PCB a[])
{ 
   
	int sumzhou = 0;
	double sumdai = 0;
	printf("名称\t到达时间\t服务时间\t完成时间\t周转时间\t带权周转时间\n");
	for(int i=0; i<=4; i++)
	{ 
   
		cout<<a[i].name<<"\t";
		printf("%d\t\t%d\t\t%d\t\t%d\t\t%.2f\n",a[i].arrive_time,a[i].service_time,a[i].exit_time,a[i].exit_time-a[i].arrive_time,(a[i].exit_time*1.0-a[i].arrive_time)/a[i].service_time*1.0);
	}
	for(int i=0; i<=4; i++)
	{ 
   
		sumzhou+=a[i].exit_time-a[i].arrive_time;
		sumdai+=(a[i].exit_time*1.0-a[i].arrive_time)/a[i].service_time*1.0;
	}
	printf("平均周转时间:%.2f 平均带权周转时间:%.2f",sumzhou*1.0/5,sumdai/5);
	system("pause");
}
void outputQue(int front,int rear)
{ 
   
	
	printf("\t当前就绪队列: " );
	for(int i=front; i<rear; i++)
	{ 
   
		cout<<Que[i].name;
	}
	cout<<endl;
}
void outputMQ(int index,int front[],int rear[])
{ 
   
	cout<<endl;
	for(int i=0; i<index; i++)
	{ 
   
		
		printf("\t%d级队列:",i+1);
		for(int j=front[i]; j<rear[i]; j++)
		{ 
   
			cout<<MQ[i][j].name;
			
		}
		cout<<endl;
	}
	cout<<endl<<endl;
}
void outsum()
{ 
   
	cout<<"先来先服务:"<<endl;
	output(fcfs);
	cout<<"短作业优先:"<<endl;
	output(sjf);
	cout<<"高响应比:"<<endl;
	output(hrrn);
	cout<<"时间片轮转:"<<endl;
	output(rr);
	cout<<"多级反馈队列:"<<endl;
	output(mfq);
}
void FCFS()
{ 
   
	top=0;
	PCB p= { 
   "0",0,0,0};
	int now = 0;
	int flag = 0; //0空闲 1运行
	int r=0;
	while(1)
	{ 
   
		//printf("%d\n",now);
		//如果当前空闲,并且不是第一次空闲,说明有进程执行完毕
		if(flag == 0&&p.name!="0")
		{ 
   
			cout<<now<<" "<<p.name<<"执行完毕"<<endl;
			p.ifrun = true;
			fcfs[top++]=p;
		}
		//如果进程全部执行完
		if(top == 5)
			break;
		//查看这一秒是否有进程到达
		for(int i=r; i<5; i++)
		{ 
   
			if(pcb[i].arrive_time == now)   //此时间有进程到达
			{ 
   
				q.push(pcb[i]); //入队
				cout<<now<<" "<<pcb[i].name<<"到达"<<endl;
				r=i+1;
			}
		}
		if(flag == 0&&!q.empty())   //空闲
		{ 
   
			//取队头执行
			p = q.front();
			q.pop();
			cout<<now<<" "<<p.name<<"开始执行"<<endl;
			p.exit_time = p.service_time+now;
			flag = p.service_time;
		}
		//下一秒
		now++;
		if(flag>0)
			flag--;
		Sleep(500);
	}
	output(fcfs);
}

void SJF()
{ 
   
	top = 0;
	int front = 0;
	int rear = 0;
	PCB p= { 
   "0",0,0,0};
	int now = 0;
	int flag = 0; //0空闲 1运行
	int r=0;
	while(1)
	{ 
   
		//printf("%d\n",now);
		//如果当前空闲,并且不是第一次空闲,说明有进程执行完毕
		if(flag == 0&&p.name!="0")
		{ 
   
			cout<<now<<" "<<p.name<<"执行完毕"<<endl;
			p.ifrun = true;
			sjf[top++]=p;
		}
		//如果进程全部执行完
		if(top == 5)
			break;
		//查看这一秒是否有进程到达
		for(int i=r; i<5; i++)
		{ 
   
			if(pcb[i].arrive_time == now)   //此时间有进程到达
			{ 
   
				Que[rear++]=pcb[i]; //入队
				cout<<now<<" "<<pcb[i].name<<"到达"<<endl;
				sort(Que+front,Que+rear,cmpSJF);
				r=i+1;
			}
		}
		if(flag == 0&&front!=rear)   //空闲
		{ 
   
			//取队头执行
			p = Que[front++];
			cout<<now<<" "<<p.name<<"开始执行"<<endl;
			p.exit_time = p.service_time+now;
			flag = p.service_time;
		}
		//下一秒
		now++;
		if(flag>0)
			flag--;
		Sleep(500);
	}
	output(sjf);
}

void HRRN()
{ 
   
	top = 0;
	int front = 0;
	int rear = 0;
	PCB p= { 
   "0",0,0,0};
	int now = 0;
	int flag = 0; //0空闲 1运行
	int r=0;
	while(1)
	{ 
   
		//printf("%d\n",now);
		//如果当前空闲,并且不是第一次空闲,说明有进程执行完毕
		if(flag == 0&&p.name!="0")
		{ 
   
			cout<<now<<" "<<p.name<<"执行完毕"<<endl;
			p.ifrun = true;
			hrrn[top++]=p;
		}
		//如果进程全部执行完
		if(top == 5)
			break;
		//查看这一秒是否有进程到达
		for(int i=r; i<5; i++)
		{ 
   
			if(pcb[i].arrive_time == now)   //此时间有进程到达
			{ 
   
				cout<<now<<" "<<pcb[i].name<<"到达"<<endl;
				Que[rear++]=pcb[i]; //入队
				r=i+1;
			}
		}
		if(flag == 0&&front!=rear)   //空闲
		{ 
   
			//计算优先权并排序
			for(int j=front; j<rear; j++)
				Que[j].quan = (Que[j].wait_time*1.0+Que[j].service_time)/Que[j].service_time;
			sort(Que+front,Que+rear,cmpHRRN);
			//取队头
			p = Que[front++];
			cout<<now<<" "<<p.name<<"开始执行"<<endl;
			p.exit_time = p.service_time+now;
			flag = p.service_time;
		}
		//下一秒
		now++;
		for(int i = front; i<rear; i++)
		{ 
   
			Que[i].wait_time++;
		}
		if(flag>0)
			flag--;
		Sleep(500);
	}
	output(hrrn);
}

void RR()
{ 
   
	int t=0;
	top = 0;
	int front = 0;
	int rear = 0;
	PCB p= { 
   "0",0,0,0};
	int now = 0;
	int flag = 0; //0空闲 1运行
	int r=0;
	int time;
	printf("请输入时间片间隔:");
	scanf("%d",&time);
	while(1)
	{ 
   
		if(t == time)//时间片用完
			t=0;
		//扫描入队
		for(int i=r; i<5; i++)
		{ 
   
			if(pcb[i].arrive_time == now)   //此时间有进程到达
			{ 
   
				cout<<now<<" "<<pcb[i].name<<"到达"<<endl;
				Que[rear++]=pcb[i]; //入队
				outputQue(front,rear);
				r=i+1;
			}
		}
		if(p.name!="0") //不是第一次
		{ 
   
			if(p.RR_time >= p.service_time)//如果已经完成服务
			{ 
   
				cout<<now<<" "<<p.name<<" "<<"结束!"<<endl;
				p.exit_time=now;
				t=0;
				rr[top++]=p;
				if(top == 5)
					break;
				p.name="0";
			}
			else if(t == 0) //如果没有完成并且时间片用完了
			{ 
   
				cout<<now<<" "<<p.name<<" "<<"时间片用完!"<<endl;
				Que[rear++]=p;
				outputQue(front,rear);
			}

		}
		if(t == 0 && front!=rear)
		{ 
   
			p = Que[front++];
			cout<<now<<" "<<p.name<<"开始执行"<<endl;
			outputQue(front,rear);
		}
		now++;
		t++;
		p.RR_time++;
		Sleep(500);
	}
	output(rr);
}

void MFQ()
{ 
   
	int t=0;
	top = 0;
	int num;
	int front[10] ;
	int rear[10] ;
	memset(front,0,sizeof(front));
	memset(rear,0,sizeof(rear));
	int time[10]= { 
   1,2,4,8,16};
	printf("请输入队列的个数(最多为5):");
	scanf("%d",&num);
	PCB p= { 
   "0",0,0,0};
	int now = 0;
	int r=0;
	int index=0;
	t=0;
	while(1)
	{ 
   
		if(t == time[index])//时间片用完
			t=0;
		//扫描入队
		for(int i=r; i<5; i++)
		{ 
   
			if(pcb[i].arrive_time == now)   //此时间有进程到达
			{ 
   
				cout<<now<<" "<<pcb[i].name<<"到达"<<endl;
				MQ[0][rear[0]++]=pcb[i]; //入队
				outputMQ(num,front,rear);
				r=i+1;
			}
		}
		if(p.name!="0") //不是第一次
		{ 
   
			if(p.RR_time >= p.service_time)//如果已经完成服务
			{ 
   
				cout<<now<<" "<<p.name<<" "<<"结束!"<<endl;
				p.exit_time=now;
				t=0;
				mfq[top++]=p;
				if(top == 5)
					break;
				p.name="0";
			}
			else if(t == 0) //如果没有完成并且时间片用完了
			{ 
   
				cout<<now<<" "<<p.name<<" "<<"时间片用完!"<<endl;
				if(index+1<=num-1)
					MQ[index+1][rear[index+1]++]=p;
				else
					MQ[index][rear[index]++]=p;
				outputMQ(num,front,rear);
			}
		}
		if(t == 0)
		{ 
   
			int ff=0;
			for(int i=0; i<5; i++)
			{ 
   
				if(front[i]!=rear[i]) // 该级队列中有进程
				{ 
   
					ff=1;
					index=i;
					break;
				}
			}
			if(ff==1)
			{ 
   
				p = MQ[index][front[index]++];
				cout<<now<<" "<<p.name<<"开始执行"<<endl;
			}
			outputMQ(num,front,rear);
		}
		now++;
		t++;
		p.RR_time++;
		Sleep(500);
	}
	output(mfq);
}

int main()
{ 
   
	int n;
	init();

	while(1)
	{ 
   
		menu();
		scanf("%d",&n);
		switch(n)
		{ 
   
			case 1:
				input();
				break;
			case 2:
				display();
				break;
			case 3:
				FCFS();
				break;
			case 4:
				SJF();
				break;
			case 5:
				HRRN();
				break;
			case 6:
				RR();
				break;
			case 7:
				MFQ();
				break;
			case 8:
				outsum();
				break;
			case 0:
				exit(1);
				break;
			default :
				printf("请输入有效选项!\n");
		}
	}

}

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/188596.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档