时间片轮转调度算法的模拟时间片轮转调度算法(RR算法)(队尾C++实现)

本文介绍了一种基于先来先服务(FCFS)原则的进程调度算法实现。通过将所有就绪进程按照到达时间排序并依次调度,确保每个进程都能获得公平的CPU时间。文章提供了完整的C++代码实现,包括进程管理、时间片轮转等关键环节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实验步骤:在书上或网上找到相关算法,进行修改,上机检验,纠错

设计思路:

(1)系统将所有就绪进程按照FCFS的原则,排成一个队列依次调度。

(2)把CPU分配给队首进程,执行一个时间片(10-100ms)。

(3)时间片用完后,系统计时器发出时钟中断,该进程将被剥夺CPU并插入就绪队列末尾。

 代码:新进程放在队列的队尾。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
struct PCB {
	int id;				//进程编号 
	char name;			//进程名字
	int arrive;			//到达时间
	int serve;			//服务时间
	int finish;			//完成时刻
	//排序优先参考到达时间,其次是服务时间 
	bool operator< (const PCB &t) const{
		if(arrive != t.arrive) return arrive < t.arrive;
		return serve < t.serve;
	};
};
const int N = 10;	//最多10个进程
const int M = 100;	//最长100个时间单位 
PCB pcb_list[N];	//进程列表
vector<PCB> table[M];	//进程时刻表
queue<PCB> que;		//进程队列
int n,t,q,sjp;	//进程数,总计时,固定时间片,运转时间片
int max_time;	//最大时间
void query() {	//查询当前是否有进程到达,有则入队
	//将当前时刻的所有进程入队
	for(int i = 0; i < table[t].size(); i++)
		que.push(table[t][i]);
}
void run() {
	cout << "当前时刻\t" << "运行进程\t" << "剩余服务时间" << endl;
	PCB cur = pcb_list[0];	//初始化当前进程
	sjp = q;	//初始化时间片 
	for(t = 0; t <= max_time; t++) {	//跑时间 
		query();	//当前是否有进程到达,有则入队
		if(que.empty()) continue;	//如果队列空,跳过
		if(!sjp || !cur.serve) {	//时间片用完了 或 当前进程运行完了,则调度 
			sjp = q;	//恢复时间片
			que.pop();	//队首出队
			if(cur.serve) que.push(cur);	//如果当前进程没有运行完,则移到队尾
			else pcb_list[cur.id].finish = t;	//运行完了,设置完成时刻 
			if(!que.empty()) cur = que.front();	//取新的队首
			else continue;	//已经空了,跳过 
		}
		cout << t << "\t\t" << cur.name << "\t\t" << cur.serve << endl;	//输出当前时刻状态 
		sjp--,cur.serve--;	//时间片-1,当前进程服务时间-1 
	}
}
void set_max_time() {
	for(int i = 0; i < n; i++)
		max_time += pcb_list[i].serve;
	max_time+=5;//多加一点避免边界问题(删掉也没关系,程序已经很完备了) 
}
int main() {
	printf("时间片轮转调度算法\n\n");
	printf("请输入进程数 时间片\n");
	cin >> n >> q;	//输入进程数和时间片时长
	printf("请输入每个进程的进程名 到达时间 服务时间\n");
	for(int i = 0; i < n; i++)
		cin >> pcb_list[i].name >> pcb_list[i].arrive >> pcb_list[i].serve;
	sort(pcb_list,pcb_list+n);	//对进程按到达时间排序
	for(int i = 0; i < n; i++) {
		pcb_list[i].id = i;	//给进程编号 
		table[pcb_list[i].arrive].push_back(pcb_list[i]);	//将进程送到时刻表 
	}
	set_max_time();	//设置最大运行时间
	run();	//开始运行
	cout << "进程名字\t" << "完成时间\t" << "周转时间\t" << "带权周转时间" << endl;
	for(int i = 0; i < n; i++) {
		int zzsj = pcb_list[i].finish-pcb_list[i].arrive;
		double dqzzsj = (double)zzsj / pcb_list[i].serve;
		printf("%c\t\t%d\t\t%d\t\t%.2lf\n",pcb_list[i].name,pcb_list[i].finish,zzsj,dqzzsj);
	}
	return 0;
}

(1)、假定系统有五个进程,每一个进程用一个进程控制块PCB来代表。进程控制块的格式 (2)、每次运行你所设计的处理器调度程序之前,为每个进程任意确定它的“要求运行时间”。 把五个进程按顺序排成循环队列,用指针指出队列连接情况。另用一标志单元记录轮到运行的进程。 (3)、处理器调度总是选择标志单元指示的进程运行。由于本实验是模拟处理器调度的功能,所以,对被选中的进程并不实际启动运行 (4)、进程运行一次后,应把该进程的进程控制块中的指针值送到标志单元,以指示下一个轮到运行的进程。同时,应判断该进程的要求运行时间与已运行时间,若该进程要求运行时间≠已运行时间,则表示它尚未执行结束,应待到下一轮时再运行。若该进程的要求运行时间=已运行时间,则表示它已经执行结束,应把它的状态修改为“结束”(E)且退出队列。此时,应把该进程的进程控制块中的指针值送到前面一个进程的指针位置。 (5)、若“就绪”状态的进程队列不为空,则重复上面(4)和(5)的步骤,直到所有进程都成为“结束”状态。 (6)、在所设计的称序中应有显示或打印语句,能显示或打印每次被选中进程的进程名以及运行一次后进称对列的变化。 (7)、为五个进程任意确定一组“要求运行时间”,启动所设计的处理器调度程序,显示或打印逐次被选中进程的进程名以及进程控制块的动态变化过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

麦与陌生人

打赏每人一元起步·小气鬼

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值