只是在一定程度上模拟实现了FCFS SJF RR PrioritySchedule 这四种调度策略 (/ω\)(///)╰(°▽°)╯☆*: .。. o(≧▽≦)o .。.:*☆
FCFS
背景知识
在操作系统中,进程调度是管理进程执行顺序的关键组件之一。先来先服务(FCFS)是一种简单的非抢占式调度算法,它按照进程到达的先后顺序来决定进程的执行次序。一旦一个进程开始执行,它将一直运行直到完成或阻塞。题目描述
你的任务是编写一个简单的进程调度模拟器,该模拟器采用先来先服务(FCFS)策略来调度一组进程。每个进程由其到达时间和所需CPU时间来表示。你需要计算这些进程的平均等待时间、平均周转时间以及平均带权周转时间。
输入格式
输入的第一行是一个整数 N (1≤N≤100),表示进程的数量。接下来的N行每行包含两个整数a和b (0≤a, b≤1000),分别表示进程的到达时间和所需的CPU时间。
输出格式
输出三行,第一行是所有进程的平均等待时间,第二行是所有进程的平均周转时间,第三行是所有进程的平均带权周转时间。结果保留两位小数。
例如:
输入
3
0 5
1 2
2 3输出
3.00
6.33
2.22
先来先服务策略调度,字面意思就是来得最早,最早调入执行。编写代码核心就是,按照到达时间
arrivalTime
进行排序。(●’◡’●)
简单C++代码示意:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Process {
int arrivalTime;
int burstTime;//运行时间
int waitingTime;
int turnaroundTime;//周转时间=等待+运行
double weightedTurnaroundTime;//带权周转=周转/运行时间
};
bool compareArrivalTime(const Process& p1, const Process& p2)
{
return p1.arrivalTime < p2.arrivalTime;
}
int main() {
int N;
cin >> N;
vector<Process> processes(N);
for (int i = 0; i < N; i++) {
cin >> processes[i].arrivalTime;
cin >> processes[i].burstTime;
}
// 按照到达时间排序进程
sort(processes.begin(), processes.end(), compareArrivalTime);
int current = 0;
double tWaitingTime = 0;
double tTurnaroundTime = 0;
double tWeightedTurnaroundTime = 0;
for (int i = 0; i < N; i++)
{
if (current < processes[i].arrivalTime)
{
current = processes[i].arrivalTime;
}
processes[i].waitingTime = current - processes[i].arrivalTime;
current += processes[i].burstTime;
processes[i].turnaroundTime = processes[i].waitingTime + processes[i].burstTime;
processes[i].weightedTurnaroundTime = (double)processes[i].turnaroundTime / processes[i].burstTime;
tWaitingTime += processes[i].waitingTime;
tTurnaroundTime += processes[i].turnaroundTime;
tWeightedTurnaroundTime += processes[i].weightedTurnaroundTime;
}
cout << fixed;
cout.precision(2);
cout << tWaitingTime / N << endl;
cout << tTurnaroundTime / N << endl;
cout << tWeightedTurnaroundTime / N << endl;
return 0;
}
SJF
背景知识
在操作系统中,进程调度是管理进程执行顺序的关键组件之一。基于短作业优先(Shortest Job First, SJF)的进程调度算法是一种常见的CPU调度策略。这种算法可以分为两种形式:非抢占式(一旦一个进程开始运行,它将一直运行直到完成或阻塞)和抢占式(如果一个新的较短的进程到达就绪队列,那么当前正在执行的进程会被中断,新的较短的进程会获得CPU)。
题目描述
编写一个程序,模拟基于非抢占式短作业优先(Shortest Job First, SJF)的进程调度算法。给定一组进程,每个进程有一个到达时间和所需的服务时间。程序应计算并输出所有进程的平均等待时间、平均周转时间和平均带权周转时间。输入格式
第一行包含一个整数N (1 ≤ N ≤ 100),表示进程的数量。
接下来的N行每行包含两个整数,分别代表进程的到达时间和所需的服务时间。
输出格式
输出三行,第一行是所有进程的平均等待时间,第二行是所有进程的平均周转时间,第三行是所有进程的平均带权周转时间。结果保留两位小数。
示例
输入
3
0 5
1 4
2 3
输出
3.33
7.33
1.92
短作业优先,但是是非抢占式的。所以主要的执行顺序还得是
arrivalTime
从小到大的次序,当执行的进程完成后,会比较已经到达进程的burstTime
,根据时间越短越先执行的原则,选择进程执行。主要的也是根据两个变量的排序。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// 进程结构体
struct Process {
int arrivalTime;
int burstTime;
int waitingTime;
int turnaroundTime;
double weightedTurnaroundTime;
int isReadyQueue;
};
// 到达比较
bool cmpAT(const Process& p1, const Process& p2) {
return p1.arrivalTime < p2.arrivalTime;
}
// 就绪队列中的比较
bool cmpBT(const Process& p1, const Process& p2) {
return p1.burstTime < p2.burstTime;
}
int main() {
int n;
cin >> n;
vector<Process> processes(n);
// 输入进程的到达时间和服务时间
for (int i = 0; i < n; i++) {
cin >> processes[i].arrivalTime;
cin >> processes[i].burstTime;
processes[i].isReadyQueue = 0;
}
// 按照到达时间对进程排序
sort(processes.begin(), processes.end(), cmpAT);
vector<Process> readyQueue;
int currTime = 0;
int completedProcesses = 0;
while (completedProcesses < n)
{
// 将 到 且 没有在就绪队列中的添加进来
for (int i = 0; i < n; i++)
{
if (processes[i].arrivalTime <= currTime && processes[i].isReadyQueue==0)
{
processes[i].isReadyQueue = 1;
readyQueue.push_back(processes[i]);
// 按照剩余时间对就绪队列中的进程排序
sort(readyQueue.begin(), readyQueue.end(), cmpBT);
}
}
if (readyQueue.empty())
{
currTime++;
continue;
}
Process currProc = readyQueue[0];
readyQueue.erase(readyQueue.begin());
currProc.waitingTime = currTime - currProc.arrivalTime;
currTime += currProc.burstTime;
currProc.turnaroundTime = currProc.waitingTime + currProc.burstTime;
currProc.weightedTurnaroundTime =(double)currProc.turnaroundTime / currProc.burstTime;
// 更新原进程列表中的进程信息
for (int i = 0; i < n; i++)
{
if (processes[i].arrivalTime == currProc.arrivalTime
&& processes[i].burstTime == currProc.burstTime) {
processes[i] = currProc;
break;
}
}
completedProcesses++;
}
double tWaitingTime = 0;
double tTurnaroundTime = 0;
double tWeightedTurnaroundTime = 0;
for (int i = 0; i < n; i++) {
tWaitingTime += processes[i].waitingTime;
tTurnaroundTime += processes[i].turnaroundTime;
tWeightedTurnaroundTime += processes[i].weightedTurnaroundTime;
}
cout << fixed;
cout.precision(2);
cout << tWaitingTime / n << endl;
cout << tTurnaroundTime / n << endl;
cout << tWeightedTurnaroundTime / n << endl;
return 0;
}
RR
背景知识
时间片轮转调度算法是一种常见的进程调度策略,它将系统中的处理器时间划分为一个个时间片,每个进程轮流执行一个时间片。如果进程在时间片结束前没有完成,则会被中断并放入就绪队列的末尾,等待下一次调度。题目描述
给定一系列进程的到达时间和所需的CPU服务时间,以及时间片大小,使用时间片轮转调度算法计算所有进程的平均等待时间、平均周转时间以及平均带权周转时间。输入格式
输入数据由多组数据组成,每组数据的第一行包含两个整数N和Q (1 ≤ N ≤ 10, 1 ≤ Q ≤ 10),分别表示进程的数量和时间片大小;接下来N行,每行两个整数,分别表示进程的到达时间和所需的服务时间。所有的时间值都是非负整数,且不会超过1000。输出格式
对于每组输入数据,输出三行:
第一行:所有进程的平均等待时间(保留两位小数)
第二行:所有进程的平均周转时间(保留两位小数)
第三行:所有进程的平均带权周转时间(保留两位小数)
示例一输入
3 1
0 5
1 3
2 2输出
4.00
7.33
2.28示例二
输入
3 2
0 5
1 3
2 2输出
4.00
7.33
2.22
时间片轮转,主要的是当执行进程的执行时间片到了,会将进程“退出”,让后面排队的进程依次获取时间片进。
总的来看,就是排队领冰淇凌,每个人都有心中想吃个数的预期值。但是每次能领取的个数是有限的,所以当领完以后,就得从新到队尾排队,这期间仍有不断想吃冰淇凌的朋友加入排队。
#include <iostream>
#include <vector>
#include <queue>
#include <iomanip>
using namespace std;
struct Process {
int id;
int arrivalTime;
int burstTime;
int remainingTime;//剩余时间
int waitingTime;
int turnaroundTime;
double weightedTurnaroundTime;
int inQ;
};
// 时间片轮转调度算法函数
void roundRobin(vector<Process>& processes, int Q) {
queue<Process> readyQueue;
int curtime = 0;
int completedProcesses = 0;
int n = processes.size();
while (completedProcesses < n) {
for (int i = 0; i < n; i++) {
if (processes[i].arrivalTime <= curtime && processes[i].remainingTime > 0 && processes[i].inQ==0)
{
processes[i].inQ = 1;
readyQueue.push(processes[i]);
}
}
if (readyQueue.empty()) {
curtime++;
continue;
}
Process curP = readyQueue.front();
readyQueue.pop();
if (curP.remainingTime > Q) {
curP.remainingTime -= Q;
curtime += Q;
for (int i = 0; i < n; i++) {
if (processes[i].arrivalTime <= curtime && processes[i].remainingTime > 0
&& processes[i].inQ==0)
{
processes[i].inQ = 1;
readyQueue.push(processes[i]);
}
}
readyQueue.push(curP);
}
else
{
curtime += curP.remainingTime;
curP.remainingTime = 0;
curP.turnaroundTime = curtime - curP.arrivalTime;
curP.waitingTime = curP.turnaroundTime - curP.burstTime;
curP.weightedTurnaroundTime = (double)curP.turnaroundTime / curP.burstTime;
completedProcesses++;
for (int i = 0; i < n; i++) {
if (processes[i].id == curP.id) {
processes[i] = curP;
break;
}
}
}
}
}
int main() {
int n, Q;
cin >> n >> Q;
vector<Process> processes(n);
for (int i = 0; i < n; i++) {
cin >> processes[i].arrivalTime;
cin >> processes[i].burstTime;
processes[i].id = i + 1;
processes[i].remainingTime = processes[i].burstTime;
processes[i].inQ = 0;
}
roundRobin(processes, Q);
double totalWaitingTime = 0;
double totalTurnaroundTime = 0;
double totalWeightedTurnaroundTime = 0;
for (int i = 0; i < n; i++) {
totalWaitingTime += processes[i].waitingTime;
totalTurnaroundTime += processes[i].turnaroundTime;
totalWeightedTurnaroundTime += processes[i].weightedTurnaroundTime;
}
cout << fixed << setprecision(2);
cout << totalWaitingTime / n << endl;
cout << totalTurnaroundTime / n << endl;
cout << totalWeightedTurnaroundTime / n << endl;
return 0;
}
优先级调度算法模拟
背景信息
在多任务操作系统中,进程调度算法决定了CPU如何在多个可运行进程中切换。抢占式优先级调度是一种常见的调度策略,其中每个进程被赋予一个优先级值,高优先级的进程比低优先级的进程更早获得CPU资源。当有更高优先级的进程到达时,当前正在执行的进程会被中断,让更高优先级的进程先执行。任务
编写一个C++程序,模拟抢占式优先级调度算法,并计算所有进程的平均等待时间、平均周转时间及平均带权周转时间。每个进程有三个属性:到达时间、CPU时间(即执行时间)和优先级(1-5级,1为最高优先级)。输入格式
第一行是一个整数n(1 ≤ n ≤ 100),表示进程的数量。
接下来的n行,每行包含三个整数arrival_time(0 ≤ arrival_time ≤ 1000)、cpu_time(1 ≤ cpu_time ≤ 700)和priority(1 ≤ priority ≤ 5),分别代表进程的到达时间、CPU时间和优先级。
输出格式
第一行输出所有进程的平均等待时间,保留两位小数。
第二行输出所有进程的平均周转时间,保留两位小数。
第三行输出所有进程的平均带权周转时间,保留两位小数。
示例
输入
3
0 10 2
2 5 3
5 7 1
输出
7.33
14.67
2.23
抢占式优先级算法 重点在于抢占 和 优先级 ,合在一起构成了,当优先级更高的作业到达后,原本在
CPU
上的进程将退出,让优先级高的上CPU
运行。简单的实现:
#include <iostream>
#include <vector>
#include <algorithm>
#include <iomanip>
using namespace std;
struct Process {
int arrival_time;
int cpu_time;
int priority;
int waitingTime;
int turnaroundTime;
double weightedTurnaroundTime;
int start_time;
int end_time;
int r_cpu_time;
};
// 到达时间排序
bool cmpArrival_time(const Process& p1, const Process& p2) {
return p1.arrival_time < p2.arrival_time;
}
int main() {
int n;
cin >> n;
vector<Process> processes(n);
for (int i = 0; i < n; i++) {
cin >> processes[i].arrival_time >> processes[i].cpu_time >> processes[i].priority;
processes[i].r_cpu_time = processes[i].cpu_time;
processes[i].start_time = -1;
}
// 按照到达时间对进程进行排序
sort(processes.begin(), processes.end(), cmpArrival_time);
int curTime = 0;
int finish = 0;
while (finish < n)
{
int hightest_prio_index = -1;
for (int i = 0; i < n; i++)
{
if (processes[i].arrival_time <= curTime && processes[i].r_cpu_time > 0) {
if (hightest_prio_index == -1 ||
(processes[i].priority < processes[hightest_prio_index].priority) ||
(processes[i].priority == processes[hightest_prio_index].priority &&
processes[i].arrival_time < processes[hightest_prio_index].arrival_time)) {
hightest_prio_index = i;
}
}
}
if (hightest_prio_index == -1) {
// 如果没有可执行的进程,时间前进到下一个到达的进程
int next_arrival = 1001; // 一个足够大的值
for (int i = 0; i < n; ++i) {
if (processes[i].arrival_time > curTime && processes[i].arrival_time < next_arrival) {
next_arrival = processes[i].arrival_time;
}
}
curTime = next_arrival;
}
else {
// 执行当前最高优先级的进程
Process* curP = &processes[hightest_prio_index];
if (curP->start_time == -1) {
curP->start_time = curTime;
}
curP->r_cpu_time--;
curTime++;
if (curP->r_cpu_time == 0) {
// 进程完成
curP->end_time = curTime;
curP->turnaroundTime = curP->end_time - curP->arrival_time;
curP->waitingTime = curP->turnaroundTime - curP->cpu_time;
curP->weightedTurnaroundTime = (double)curP->turnaroundTime / curP->cpu_time;
finish++;
}
}
}
double totalWaitingTime = 0;
double totalTurnaroundTime = 0;
double totalWeightedTurnaroundTime = 0;
for (int i = 0; i < n; i++)
{
totalWaitingTime += processes[i].waitingTime;
totalTurnaroundTime += processes[i].turnaroundTime;
totalWeightedTurnaroundTime += processes[i].weightedTurnaroundTime;
}
cout << fixed << setprecision(2);
cout << totalWaitingTime / n << endl;
cout << totalTurnaroundTime / n << endl;
cout << totalWeightedTurnaroundTime / n << endl;
return 0;
}