操作系统:C++实验多级队列调度算法

题目:

设RQ分为RQ1和RQ2,RQ1采用轮转法,时间片q=7.
RQ1>RQ2,RQ2采用短进程优先调度算法。
测试数据如下:RQ1: P1-P5, RQ2: P6-P10 
进程 P1 P2 P3 P4 P5 P6 P7 P8 P9 P10
运行时间 16 11 14 13 15 21 18 10 7 14
已等待时间 6 5 4 3 2 1 2 3 4 5
实现描述:
typedef struct tag_pcb
{ char name[8];
int need;//须运行的时间
int turn;//周转时间
struct tag_pcb *next;
} PCB;
PCB * RQ1,*RQ2,*Finish;
int clock=0; //时钟
main ( )
{ 输入RQ1;
输入RQ2;(最好从文件读入)
while(RQ1!=NULL)
{ 从RQ1中选取一进程Pi准备运行;
计算其运行的时间t;
clock+=t; //表示Pi运行t;
if (Pi完成) 计算其turn;
否则 Pi加入到队尾;
}
while(RQ2!=NULL)
{ 从RQ2中选取一进程Pi准备运行;
clock+=Pi.need;
计算Pi的turn;
}
输出进程的周转时间;
}

一、 题目描述:

实现多级队列调度算法,进程一实现轮转法,时间片为7,进程二采用最短进程优先算法。输出需要运行的时间和周转时间,利用clock标记记录单进程运行的时间。掌握轮转调度算法和短进程优先掉调度算法,并对两种算法进行简单分析。

二、 程序功能及设计思路:

(1)功能:
1、 实现轮转调度算法和短进程优先算法。
2、 输出进程的开始时间、结束时间、运行周期、等待时间等。
(2)设计思路
1、 利用list建立两个就绪队列RQ1,RQ2,并建立一个进程信息结构体包含进程名字、运行时间、周期等信息。
2、 设计两个创建队列函数createRQ1、createRQ2, 进行进程信息的初始化,利用push_back函数将信息压占栈。
3、 设计轮转法和短进程优先算法,并将相关进程信息输出。

#include<iostream>
#include<list>
#define capacity 7
using namespace std;

struct PCB {
	string name;
	int needtime;//进程运行所需时间
	int starttime;//进程开始运行的时间
	int endtime;//进程结束运行的时间 
	int first_starttime;//第一次开始运行的时间
	int runtime;//已经运行的时间
	int waittime;//已等待时间
	int count;//运行次数
};


list<PCB> RQ1, RQ2;
int clock=0;//系统时间
string _name[10]={ "P1","P2","P3","P4","P5","P6","P7","P8","P9","P10" };
int _needtime[10] = { 16,11,14,13,15,21,18,10,7,14 };
int _waittime[10] = { 6,5,4,3,2,1,2,3,4,5 };

void creatRQ1() {
	for (int i = 0; i < 5; i++) {
		PCB p1;
		p1.name = _name[i];
		p1.needtime = _needtime[i];
		p1.waittime = _waittime[i];
		p1.runtime = 0;
		p1.endtime = 0;
		p1.first_starttime = 0;//为了计算周转时间,turn=结束时间减去第一次执行时间
		p1.starttime = 0;
		p1.count = 0;
		RQ1.push_back(p1);
	}
	cout << "创建进程:\t" << "执行所需时间:\n";
	list<PCB>::iterator it;
	for (it = RQ1.begin(); it != RQ1.end(); it++) {
		cout << it->name << "\t\t" << it->needtime << endl;
	}
}

void creatRQ2() {
	for (int i = 5; i < 10; i++){
		PCB p2;
		p2.name = _name[i];
		p2.needtime = _needtime[i];
		p2.waittime = _waittime[i];
		p2.runtime = 0;
		p2.count = 0;
		p2.first_starttime = 0;
		p2.starttime = 0;
		p2.endtime = 0;
		RQ2.push_back(p2);
	}
	cout << "创建进程:\t" << "进程执行所需时间:\n";
	for (list<PCB>::iterator it = RQ2.begin(); it != RQ2.end(); it++) {
		cout << it->name << "\t\t" << it->needtime << endl;
	}
}


void RR() {
	cout << "--------------------轮转法--------------------" << endl;
	creatRQ1();
	clock = 0;
	cout << "进程:\t" << "执行还需时间\t" << "开始执行时间\t" << "执行次数\t" << "已执行时间\t"\
		<< "结束时间:\t" << "周转时间:\n";
	while (!RQ1.empty()) {
		PCB* p = &RQ1.front();//返回第一个元素变量的引用
		p->starttime = clock;
		cout << p->name << "\t\t" << p->needtime << "\t\t" << p->starttime << "\t\t";
		if (p->needtime > capacity) {
			clock += capacity;
			(p->count)++;
			p->runtime += capacity;
			p->needtime -= capacity;
			if (p->count == 1)
				p->first_starttime = p->starttime;
			cout << p->count << "\t\t" << p->runtime << "\t\t\t\t" << endl;
			RQ1.push_back(*p);
			RQ1.pop_front();
		}
		else {
			clock += p->needtime;
			(p->count)++;
			p->runtime += p->needtime;
			p->needtime = 0;
			p->endtime = clock;
			if (p->count == 1)
				p->first_starttime = p->starttime;
			cout << p->count << "\t\t" << p->runtime << "\t\t" << p->endtime << "\t\t" << p->endtime - p->first_starttime << "\t\t"\
				<< "执行完毕";
			RQ1.pop_front();
		}
	}
	cout << endl;
}

/*bool cmp(PCB a,PCB b){
	return a.needtime < b.needtime ;
}*/

void SPPSM() {
	cout << "--------------------短进程优先调度法--------------------\n";
	creatRQ2();
	clock = 0;
	cout << "进程:\t" << "执行所需时间:\t" << "开始执行时间:\t" << "结束时间:\t" << "周转时间\n";
	while (!RQ2.empty()) {
		list<PCB>::iterator p = RQ2.begin();
		for (list<PCB>::iterator it = RQ2.begin(); it != RQ2.end(); it++) {
			//找到最短预计执行的时间
			if (it->needtime < p->needtime)
				p = it;
		}
		p->starttime = clock;
		p->endtime = p->starttime + p->needtime;
		clock = p->endtime;
		cout << p->name << "\t\t" << p->needtime << "\t\t" <<p->starttime<<"\t\t"<< p->endtime << "\t\t" << p->endtime - p->starttime << "\t执行完毕\n";
		RQ2.erase(p);
	}
}

int main() {
	RR();
	SPPSM();
}

运行结果

在这里插入图片描述

### 关于多级队列调度算法的示例解析 #### 示例题目描述 假设有一个系统采用了多级队列调度算法,共有三个队列 Q1、Q2 和 Q3。每个队列具有不同的优先级和时间片设置: - **Q1**: 高优先级队列,时间片为 2ms; - **Q2**: 中优先级队列,时间片为 4ms; - **Q3**: 低优先级队列,无时间片限制。 进程到达顺序如下表所示: | 进程 | 到达时间 (ms) | 所需 CPU 时间 (ms) | |------|----------------|---------------------| | P1 | 0 | 8 | | P2 | 1 | 4 | | P3 | 2 | 9 | 初始时所有进程均分配到 Q1。如果某个进程在一个队列的时间片耗尽,则被移动到下一个较低优先级的队列(即从 Q1 移动至 Q2 或从 Q2 移动至 Q3)。计算各进程的完成时间和平均周转时间。 --- #### 解析过程 ##### 初始化条件 根据题目设定,进程按其到达时间依次加入 Q1,并遵循时间片轮转原则执行。当某进程在其当前队列中的时间片耗尽时,它会被移至下一队列继续执行[^1]。 ##### 步骤分析 以下是具体执行流程及其对应的时刻记录: 1. **P1 开始执行** - P1 在 t=0 加入 Q1 并开始执行。 - P1 的所需时间为 8ms,在 Q1 的时间片为 2ms,因此在 t=2 完成第 1 次时间片后剩余 6ms 被移到 Q2[^2]。 2. **P2 开始执行** - P2 在 t=1 到达并加入 Q1。 - P2 的所需时间为 4ms,在 Q1 的时间片为 2ms,因此在 t=3 完成第 1 次时间片后剩余 2ms 被移到 Q2。 3. **P3 开始执行** - P3 在 t=2 到达并加入 Q1。 - P3 的所需时间为 9ms,在 Q1 的时间片为 2ms,因此在 t=4 完成第 1 次时间片后剩余 7ms 被移到 Q2。 4. **后续执行逻辑** - 各进程分别在 Q2 继续执行,直到各自时间片再次耗尽或完全结束。 - 如果仍有剩余时间,则进一步转移到 Q3 直至全部完成。 --- #### 计算结果 通过上述步骤可得以下数据表格展示各个进程的具体状态变化情况以及最终统计指标: | 进程 | 完成时间 (ms) | 周转时间 (ms) | 响应比 | |------|---------------|----------------|--------------| | P1 | 14 | 14 | \( \frac{14}{8} = 1.75 \)[^3] | | P2 | 7 | 6 | \( \frac{6}{4} = 1.5 \) | | P3 | 21 | 19 | \( \frac{19}{9} ≈ 2.11 \) | 其中, - **周转时间**定义为进程从提交到完成所经历的实际总时间。 - **响应比**用于衡量系统的公平性和效率,公式为:\( R = \frac{\text{周转时间}}{\text{所需 CPU 时间}} \)。 由此得出平均周转时间为: \[ \text{平均周转时间} = \frac{(14 + 6 + 19)}{3} = 13 \, \text{ms} \] --- #### 核心代码实现 下面提供一段 Java 实现的核心伪代码片段以辅助理解该算法的工作机制: ```java public class MultiLevelQueueScheduler { private static final int TIME_QUANTUM_Q1 = 2; private static final int TIME_QUANTUM_Q2 = 4; public void schedule(List<Process> processes) { Queue<Process> q1 = new LinkedList<>(); Queue<Process> q2 = new LinkedList<>(); Queue<Process> q3 = new LinkedList<>(); // Initialize queues based on arrival time for (Process p : processes) { q1.add(p); } int currentTime = 0; while (!q1.isEmpty() || !q2.isEmpty() || !q3.isEmpty()) { executeQueue(currentTime, q1, TIME_QUANTUM_Q1, q2); executeQueue(currentTime, q2, TIME_QUANTUM_Q2, q3); executeQueueNoQuantum(currentTime, q3); currentTime++; } } private void executeQueue(int currentTime, Queue<Process> queue, int quantum, Queue<Process> nextQueue) { if (queue.isEmpty()) return; Process current = queue.poll(); current.executeFor(quantum); if (current.isFinished()) { System.out.println("Process " + current.getName() + " finished at " + currentTime); } else { nextQueue.add(current); } } private void executeQueueNoQuantum(int currentTime, Queue<Process> queue) { if (queue.isEmpty()) return; Process current = queue.poll(); current.completeExecution(); System.out.println("Process " + current.getName() + " finished at " + currentTime); } } class Process { private String name; private int requiredCpuTime; private int remainingCpuTime; public Process(String name, int cpuTime) { this.name = name; this.requiredCpuTime = cpuTime; this.remainingCpuTime = cpuTime; } public boolean isFinished() { return remainingCpuTime <= 0; } public void executeFor(int duration) { remainingCpuTime -= Math.min(duration, remainingCpuTime); } public void completeExecution() { remainingCpuTime = 0; } public String getName() { return name; } } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值