【操作系统】多级队列调度算法(完整代码)

目录

问题描述

功能描述

代码实现


问题描述

设进程优先级 RQ 分为 RQ1、RQ2 和 RQ3;
RQ1>RQ2>RQ3 (优先级:1>2>3);
RQ1 队列:采用轮转法,时间片 q=4; 每个进程最多可连续轮 2 次;
RQ2 队列:采用轮转法,时间片 q=8; 每个进程只能轮转 1 次;
RQ3 队列:采用 短进程(还有多久结束) 优先调度,每个进程运行直至 结束。

 

实现描述:
typedef struct tag_pcb
{ char name[8];
int need;//需运行的时间
int turn;//周转时间
struct tag_pcb *next;
} PCB;
PCB * RQ1,*RQ2,*RQ3,*Finish;
int clock=0; //时钟
main ( )
{ 输入 RQ1;
输入 RQ2; (最好从文件读入)
while(条件?每个进程最多轮转 2 次)
从 RQ1 中选取一进程 Pi 准备运行;
记录其本次实际运行的时间 t(不超过时间片);
clock+=t; //表示 Pi 运行 t;
if (Pi 完成) 计算其 turn;
否则
下一次轮转 Pi 加入到 RQ2 队尾 ?;
}
while(条件?)
{
从 RQ2 中选取一进程 Pi 准备运行;
记录其本次实际运行的时间 t(不超过时间片)
clock+=t;
if (Pi 完成) 计算其 turn;
否则
Pi 加入到 RQ3 队尾
}
while(条件?)
{
从 RQ3 中选取一进程 Pi 准备运行;
记录其本次实际运行的时间 t;
clock+=t;
计算 Pi 的 turn;
}
输出每个进程的周转时间;
}

功能描述

结构体PCB表示进程。RQ1,RQ2,RQ3具有 优先级的就绪队列。

优先级高的进程先执行,进程运行一个时间片后,没有运行完则加入到下一级队列尾,时间片增加一倍。(RQ1中Pi运行结束后加入 RQ2队尾)

若需要运行时间小于轮转时间,进行短进程优先调度。 (RQ2中Pi运行结束后加入RQ3队尾,不再轮转)
计算周转时间:等待时间 (clock) +运行时间 (min{需要运行时间,时间片长度})

代码实现

在两次轮转中进行操作:RQ1->RQ2,RQ2->RQ3,轮转到的进程需要时间小于一个时间片的时间,则执行完成 ;或者,进程运行一个时间片,然后需要运行时间  -= 时间片长度。写成一个函数:

轮转法:RR(PCB*& rq,PCB*& rq1, int span,int &clock) 

//轮转rq队列,符合条件的进程加入rq1队尾。span为时间片长度。传入clock进行计算周转时间,然后还要返回clock的值。

void Insert(PCB*& rq, PCB*& a)//在进程序列rq最后插入一个进程a
{
	PCB* q = rq;
	while (q->next != NULL) q = q->next;//结尾处
	PCB* temp = new PCB;//复制
	temp->name = a->name; temp->need = a->need;
	temp->turn = a->turn; temp->count = a->count;
	temp->next = NULL;
	q->next = temp;
}

void RR(PCB*& rq,PCB*& rq1, int span,int &clock)
{
	while (rq->next != NULL)
	{
		PCB* p = rq->next;
		
		int isFinish = 0;

		if (p->need <= span)
		{
			clock += p->need;
			isFinish = 1;
			p->count--;
		}
		else//need>span 
		{
			clock += span;
			p->need -= span;
			p->count--;
		}
		
		p->turn += clock;//更改周转时间
		//输出
		if (isFinish == 1)
		{
			cout << p->name << ":完成,周转时间为:" << p->turn << endl;
			finish.push_back(p);
		}
		else
		{
			cout << p->name << ":未完成,周转时间为:" << p->turn << endl;
			//没结束移到队列最后面
			Insert(rq1, p);
		}
		
		if (p->next == NULL)break;
		rq->next = p->next;
		delete p;
	}
}

然后进行短进程优先调度:每次选出队列中需要运行时间最短的进程->运行进程->进程完成,直到队列为空。

短进程:int minTime(PCB*& rq, PCB*& t) //选出最短,用t返回,返回值-1表示队列空。

              void SPPSM(int clock) //将选出的进程运行完,clock计算周转时间。

int minTime(PCB*& rq, PCB*& t)//找到队列中需要运行时间最小的一个进程
{
	if (rq->next == NULL)
	{
		t = NULL;
		return -1;
	}
	PCB* pre = rq;
	PCB* p = rq->next, * q = NULL;
	int min = 100;
	while (p!=NULL)
	{
		if (p->need < min)
		{
			q = pre;//指向最小的前一个
			min = p->need;
		}
		p = p->next;
		pre = pre->next;
	}
	if (q == NULL)return -1;
	t = q->next;
	if (t->next == NULL)q->next = NULL;
	else q->next = q->next->next;
	return 1;
}


void SPPSM(int clock)
{
	PCB* p = new PCB;
	while (minTime(RQ3, p)==1)
	{
		clock += p->need;
		p->need = 0;
		p->turn += clock;
		cout << p->name << ":完成,周转时间为:" << p->turn << endl;
	}
}

其他部分代码:

#include<iostream>
#include<fstream>
#include<vector>
using namespace std;
#include<string>

typedef struct tag_pcb
{
	string name;
	int need;//需要运行时间
	int turn;//周转时间 等待和运行时间
	int count;//已经轮转次数
	struct tag_pcb* next = NULL;
}PCB;
PCB* RQ1 = new PCB, * RQ2 = new PCB, * RQ3 = new PCB;
vector<PCB*> finish;

int span1 = 4, span2 = 8;//时间片长度

void readfile()
{
	ifstream ifs("test1.txt");
	if(!ifs.is_open())
	{
		cout << "打开文件失败!" << endl;
		return;
	}
	PCB* current = RQ1;

	while (!ifs.eof())
	{
		PCB* p = new PCB;
		ifs >> p->name >> p->need >> p->turn;
		p->count = 3;
		current->next = p;		
		current = current->next;
	}
	ifs.close();

	ifstream ifs1("test2.txt", ios::in);
	if (!ifs1.is_open())
	{
		cout << "打开文件失败!" << endl;
		return;
	}
	current = RQ2;

	while (!ifs1.eof())
	{
		PCB* p = new PCB;
		ifs1 >> p->name >> p->need >> p->turn;
		p->count = 1;
		current->next = p;
		current = current->next;
	}
	ifs1.close();
}


int main()
{
	//读RQ1 RQ2
	readfile();
	int clock = 0;//时钟

	cout << "----------" << endl;
	RR(RQ1,RQ2,span1,clock);
	cout << "----------" << endl;
	RR(RQ2,RQ3, span2,clock);

	PCB* p = RQ3->next;	
	SPPSM(clock);
	cout << endl;
	return 0;
}

文件格式为上面表格的转置(Pi need turn)。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值