You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

操作系统轮转调度算法代码结果不符问题排查求助

问题分析:你的代码结果是正确的,预期结果存在偏差

首先,先帮你理清这个轮转调度(RR)案例的正确时间线,你会发现你的代码输出的结果才是符合RR调度规则的正确结果,而你之前的预期存在偏差。

正确的RR调度时间线(时间片=3,所有进程0时刻到达)

我们一步步拆解调度过程:

  • 0-3:P1运行,剩余突发时间21,时间推进到3
  • 3-6:P2运行,剩余突发时间0(完成),完成时间=6 → 周转时间=6-0=6,等待时间=6-3=3
  • 6-9:P3运行,剩余突发时间0(完成),完成时间=9 → 周转时间=9-0=9,等待时间=9-3=6
  • 9-12:P1运行,剩余突发时间18,时间推进到12
  • 12-15:P1运行,剩余突发时间15,时间推进到15
  • 15-18:P1运行,剩余突发时间12,时间推进到18
  • 18-21:P1运行,剩余突发时间9,时间推进到21
  • 21-24:P1运行,剩余突发时间6,时间推进到24
  • 24-27:P1运行,剩余突发时间3,时间推进到27
  • 27-30:P1运行,剩余突发时间0(完成),完成时间=30 → 周转时间=30-0=30,等待时间=30-24=6

所以最终的正确统计结果就是你代码输出的:

  • 等待时间:P1=6、P2=3、P3=6
  • 周转时间:P1=30、P2=6、P3=9
  • 平均周转时间15.0000,平均等待时间5.0000

你的代码逻辑验证

你的代码核心逻辑是通过两层循环模拟RR调度:外层循环控制调度轮次,内层循环遍历所有进程,处理未完成的进程。

  • 每次处理进程时,如果剩余突发时间≤时间片,就直接计算完成时间(tat[i] = temp + bu[i])并标记进程完成;如果大于时间片,就减去时间片并推进累计时间。
  • 这个逻辑准确模拟了RR调度的“循环遍历未完成进程,每次分配时间片”的规则,所以计算结果是正确的。

可选改进点:更贴近真实队列的实现

你的代码目前假设所有进程都在0时刻到达,如果需要支持非0到达时间的场景,或者更贴近真实调度队列的逻辑,可以改用队列结构实现,这样代码可读性和扩展性更好:

#include<stdio.h>

typedef struct {
    int id;
    int burst;
    int arrival;
    int remaining;
} Process;

int main() {
    int n, t;
    float awt = 0, att = 0;
    printf("Enter the no of processes -- ");
    scanf("%d", &n);
    Process proc[n];
    int queue[n], front = 0, rear = 0;
    int current_time = 0, completed = 0;
    int tat[n], wt[n];

    for (int i = 0; i < n; i++) {
        proc[i].id = i+1;
        printf("\nEnter Burst Time for process %d -- ", i+1);
        scanf("%d", &proc[i].burst);
        proc[i].remaining = proc[i].burst;
        proc[i].arrival = 0; // 可修改为输入到达时间
        queue[rear++] = i;
    }
    printf("\nEnter the size of time slice -- ");
    scanf("%d", &t);

    while (completed < n) {
        int idx = queue[front++];
        front %= n;
        if (proc[idx].remaining <= t) {
            current_time += proc[idx].remaining;
            tat[idx] = current_time - proc[idx].arrival;
            wt[idx] = tat[idx] - proc[idx].burst;
            proc[idx].remaining = 0;
            completed++;
        } else {
            current_time += t;
            proc[idx].remaining -= t;
            queue[rear++] = idx;
            rear %= n;
        }
    }

    printf("\n\tPROCESS\t BURST TIME \t WAITING TIME\tTURNAROUND TIME\n");
    for (int i = 0; i < n; i++) {
        printf("\t%d \t %d \t\t %d \t\t %d \n", proc[i].id, proc[i].burst, wt[i], tat[i]);
        awt += wt[i];
        att += tat[i];
    }
    printf("\nThe Average Turnaround time is -- %f", att/n);
    printf("\nThe Average Waiting time is -- %f ", awt/n);
    return 0;
}

这个版本用队列模拟了真实的RR调度流程,能更直观地体现“进程完成一次时间片调度后回到队尾”的规则。

内容的提问来源于stack exchange,提问作者niizz

火山引擎 最新活动