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

操作系统实验一进程调度算法模拟_常用的进程调度算法有今日闲来无聊,发现很早之前写的操作系统实验还没有整理,再加上有很多人问,索性就发成博客吧。实验一进程调度算法一、实验目的  用高级语言编写和调试一个进程调度程序,以加深对进程的概念及进程调度算法的理解.二、实验指导设计一个有N个进程共行的进程调度程序。  进程调度算法:分别采用先来先服务算法、短作业优先算法、高响应比优先算法实现。  每个进程用一个进程控制块(PCB)表示。…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

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

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

#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.net/188596.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • ODBC学习笔记—SQLAllocHandle

    ODBC学习笔记—SQLAllocHandleSQLAllocHandle函数定义:顾名思义,该函数就是用来分配句柄的,句柄类型参考参数详解。SQLRETURNSQLAllocHandle(     SQLSMALLINT     HandleType,     SQLHANDLE     InputHandle,     SQLHANDLE*     OutputHandlePtr);参数详解:Handl

    2022年7月14日
    15
  • SimpleDateFormat日期格式解析

    SimpleDateFormat日期格式解析先看一个代码示例:运行结果:字符串"yyyy-MM-ddhh:mm:ss",其中:yyyy:代表年(不去区分大小写)假设年份为2017"y"

    2022年7月3日
    21
  • python3菜鸟教程笔记

    python3菜鸟教程笔记python2和python3的一些差异:*print函数变了,python3中的print函数必须要加括号*xrange函数合并到了range中,2到5的序列可以直接用range(2,5

    2022年7月6日
    23
  • Spring Cloud与Dubbo的完美融合之手「Spring Cloud Alibaba」[通俗易懂]

    Spring Cloud与Dubbo的完美融合之手「Spring Cloud Alibaba」[通俗易懂]很早以前,在刚开始搞SpringCloud基础教程的时候,写过这样一篇文章:《微服务架构的基础框架选择:SpringCloud还是Dubbo?》,可能不少读者也都看过。之后也就一直有关于这两个框架怎么选的问题出来,其实文中我有明确的提过,SpringCloud与Dubbo的比较本身是不公平的,主要前者是一套较为完整的架构方案,而Dubbo只是服务治理与RPC实现方案。由于Dubbo在…

    2022年5月27日
    39
  • 在一台2010年的老电脑上安装黑群辉dsm5.2并完成外网访问与洗白操作

    在一台2010年的老电脑上安装黑群辉dsm5.2并完成外网访问与洗白操作背景我和媳妇的手机容量都快要满了,主要是手机存储了大量的照片和视频,所以考虑个解决方案给手机瘦身。方案要满足一下几个要求:1、数据非常重要,一定要保证数据的可靠性;2、自动完成照片的比较,然后上传;3、照片需要满足随时、随地查看;4、保证数据的安全及私密性,最好不使用公共网盘服务(怕开发商做恶)5、总投入费用不超过300块钱。方案对比方案1(最优雅):使用手机厂商自带的云存储服务,以appleicloud为例,50G的存储已经不够用了,需要升级到200G的方案,一个月就是21块钱,一年是252

    2022年6月12日
    52
  • qmap的书写格式linux,QMap 键值存储「建议收藏」

    qmap的书写格式linux,QMap 键值存储「建议收藏」Qt中的QMap介绍与使用,在坛子里逛了一圈,发现在使用QMap中,出现过很多的问题,Map是一个很有用的数据结构。它以“键-值”的形式保存数据。在使用的时候,通过提供字符标示(键)即可得到想要的数据。这个“数据”即可以是一个字符串,也可以是任意对象,当然也包括自己定义的类对象。说明:map是以值传递的形式保存数据的。1.基本应用下面以“键-值”都是QString的例子说明QMap的基本使用方法…

    2022年5月7日
    74

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号