模拟进程调度程序

模拟进程调度程序

只是在一定程度上模拟实现了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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值