操作系统_多级反馈队列调度算法

30 篇文章 0 订阅
2 篇文章 0 订阅

1、设置 N 个就绪进程队列,即队列 0,队列 1,……,队列 N-1,用于存放就绪进程。每个队列
优先级不同,且从队列 0 到队列 N-1,优先级依次递减。 
2、不同队列中的进程所赋予的时间片长度不同;优先级越低,时间片越长,比如,队列 0 中进程
的时间片为 5,队列 1 中进程的时间片为 10 等等。
3、在队列内部,进程之间采用先来先服务(FCFS)算法辅以时间片限时机制进行调度:位于队
列头部的进程(队首进程)先执行,如果在时间片限时内,它执行结束,则从本级队列移除;如
果它时间片内未能运行结束,则将它移入下一级队列末尾(若本级队列是最低优先级队列,则移
入本级队列末尾),然后按它当前所在新队列给它分配新的时间片。 
4、当进程到达内存后,进入队列 0 末尾,并给它分配队列 0 规定的时间片。 
5、优先执行高优先级队列中的队首进程,若高优先级队列中没有就绪进程,则执行下一级优先级
队列中的队首进程。 
6、正在执行低优先级队列中的队首进程时,有新的进程到达高优先级队列,则立即中断低优先级
进程,并切换到高优先级进程执行。 

!和书上的实现稍有不同!

结构体:

struct SPCB
{
	int pid; // 进程号
	int arrivalTime; // 到达时间
	int workTime; // 服务时间
	int remainingTime; // 剩余服务时间
	int timeSlice; // 剩余时间片
	int startTime; // 开始时间。必要时,可在 mfqSchedule 函数中使用,用于记录进程开始执行的时间
	int endTime; // 进程完成服务的时间。必要时,可在 mfqSchedule 函数中使用,用于记录进程完成服务的时间
};

 

主函数:

int main()
{
	int m, n; // m 为队列数量,n 为进程数量
	int i;

	cin >> m >> n; // 输入队列数量和进程数量
	vector<int> timeSlice(m); // t 为整型数组,存放 m 级队列的时间片长度
	vector<SPCB> pcb(n);

	for (i = 0; i < m; i++)
	{
		cin >> timeSlice[i]; // 输入 m 级队列的时间片长度;一般来说,后一级队列的时间片长度大于前一级,比如,后一级时间片长度是前一级的 2 倍
	}

	for (i = 0; i < n; i++)
	{
		cin >> pcb[i].arrivalTime; // 输入第 i 个进程的到达时间
		cin >> pcb[i].workTime; // 输入第 i 个进程的服务时间

		pcb[i].pid = i; // 第 i 个进程的进程号取为 i
		pcb[i].remainingTime = pcb[i].workTime; // 剩余服务时间初始化为服务时间
		pcb[i].timeSlice = timeSlice[0]; // 剩余时间片初始化为最高优先级队列的时间片长度
		pcb[i].startTime = -1; // 开始时间初始化为 -1,表示此时开始时间记录是无效值
	}

	mfqSchedule(pcb, timeSlice);

	/*
	
	
	for (int ii = 0; ii < pcb.size(); ii++)
	{
		cout << endl;
		cout <<"进程"<<ii<<endl<<"进程开始时间:"<< pcb[ii].startTime << " " <<"进程结束时间:"<< pcb[ii].endTime << endl;
	}
*/
	return 0;
}

多级反馈队列函数实现:

void mfqSchedule(vector<SPCB> &pcb, const vector<int> &timeSlice)
{
	int i1 = 0;
	int t = timeSlice.size();
	int flag=0;//退出主循环条件
	vector<vector<SPCB>> a;
	a.resize(t);//定义队列大小
	//int flag = 0;//判断是否有在低优先级的时候有进程插入如果有置为1
	for (i1; i1 < 1000; i1++)//主要循环
	{

		//对队列中的进程操作
		int i3 = 0;
		for (i3; i3 < (int)t; i3++)
		{
			if(a[i3].empty())
			{
				
			}
			else
			{
				if (a[i3].front().remainingTime == a[i3].front().workTime)
				{
					pcb[a[i3].front().pid].startTime = i1-1;//开始时间
				}
					a[i3].front().remainingTime--;
					a[i3].front().timeSlice--;
					if (a[i3].front().remainingTime == 0)//进程pid1结束
					{
						int pid1 = a[i3].front().pid;
						pcb[pid1].endTime = i1;//结束时间
						a[i3].erase(a[i3].begin());//删除开头
						if (a[i3].empty())
							break;
					}
					if (a[i3].front().timeSlice == 0)//进程在时间片完还未结束
					{
						if (i3 == t - 1)//如果是优先级最低队列,则放到此队列末尾
						{
							a[i3].front().timeSlice = timeSlice[i3];//重置剩余时间片
							a[i3].push_back(a[i3].front());
							a[i3].erase(a[i3].begin());
						}
						else//如果不是优先级最高的队列,则放入更低优先级队列末尾
						{
							a[i3].front().timeSlice = timeSlice[i3 + 1];//重置剩余时间片
							a[i3 + 1].push_back(a[i3].front());
							a[i3].erase(a[i3].begin());
						}
					}
					break;
			}
		}
	
		//判断是否有进程需要插入,有则放入队列0末尾
		int i2 = 0;
		for (i2; i2 < pcb.size(); i2++)
		{
			if (pcb[i2].arrivalTime == i1)
			{
				a[0].push_back(pcb[i2]);
				//pcb[i2].startTime = i1;//开始时间
				flag++;
			}
		}

	}

	//输出平均周转时间
	float sum=0;
	int i0 = 0;
	for (i0; i0 < (int)pcb.size(); i0++)
	{
		sum += pcb[i0].endTime - pcb[i0].arrivalTime;
	}
	sum=sum / (pcb.size());
	printf("%.3f", sum);
	cout << endl;

	//输出平均带权周转时间
	float sum1 = 0;
	int i00 = 0;
	for (i00; i00 < (int)pcb.size(); i00++)
	{
		//sum1 += (float)(pcb[i00].endTime - pcb[i00].arrivalTime)/(pcb[i00].endTime - pcb[i00].startTime);
		sum1 += (float)(pcb[i00].endTime - pcb[i00].arrivalTime) / pcb[i00].workTime;
	}
	sum1 = sum1 / (pcb.size());
	printf("%.3f", sum1);
}

主循环只有1000次,也没有设置退出循环的条件。可以自己改动。

                                                                                                                                                                                                              小旻

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值