You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

带到达时间的SJF调度算法代码异常问题求助

问题分析与修复方案

我仔细看了你的带到达时间的SJF调度代码,确实存在几个核心问题导致重复进程ID、周转/等待时间计算不符合预期的情况,咱们一步步拆解修复:

1. 进程调度排序逻辑错误(直接导致重复ID)

你第二段排序循环的逻辑完全偏离了非抢占式SJF的核心逻辑,而且语法上的疏漏加剧了问题:

  • 用rafagasum(所有进程burst时间总和)判断进程是否到达,这完全错误,应该用当前已推进到的时间点来判断
  • if语句缺少大括号,不管条件是否满足,都会执行后面的进程交换操作,直接导致进程被错误覆盖,出现重复ID
  • 没有动态更新最短burst的候选值,无法正确选中已到达的最短作业

修复后的调度逻辑

替换掉原代码中那段错误的排序循环,改用以下逻辑(核心是每次从已到达且未完成的进程中选最短burst的作业执行):

int current_time = 0;
int completed = 0;
int selected;

// 先按到达时间排序(你的这部分逻辑是对的,保留并优化了内层循环起始点)
for (i=0;i<n;i++){
    for(j=i+1;j<n;j++){
        if(p[i].tL > p[j].tL){
            aux=p[j];
            p[j]=p[i];
            p[i]=aux;
        }
    }
}

// 非抢占式SJF核心调度逻辑
while (completed < n) {
    // 寻找当前时间点已到达的最短burst进程
    selected = -1;
    int min_burst = INT_MAX;
    for (i=0; i<n; i++) {
        if (p[i].tL <= current_time && p[i].rafaga > 0 && p[i].rafaga < min_burst) {
            min_burst = p[i].rafaga;
            selected = i;
        }
    }

    if (selected == -1) {
        // 没有进程到达,时间推进到下一个进程的到达时间
        current_time++;
        continue;
    }

    // 执行选中的进程
    current_time += p[selected].rafaga;
    // 直接计算周转时间和等待时间(避免后续单独循环的错误)
    p[selected].tP = current_time - p[selected].tL;
    p[selected].tE = p[selected].tP - p[selected].rafaga;
    p[selected].rafaga = 0; // 标记为已完成
    completed++;
}

2. 等待/周转时间计算逻辑错误

你原有的计算方式是假设进程按固定顺序执行,但SJF的执行顺序是动态选择的,不能简单累加前一个进程的burst时间。正确的计算逻辑应该是:

  • 周转时间(tP)= 进程完成时间 - 进程到达时间
  • 等待时间(tE)= 周转时间 - 进程burst时间

上面的调度逻辑中已经直接完成了这两个值的计算,不需要再单独写循环处理。

3. 其他细节修复

  • 补充必要的头文件:#include <stdio.h>、#include <limits.h>(否则INT_MAX会报错)
  • 初始化结构体成员,避免垃圾值干扰计算
  • 修正代码中转义的<和&符号(原代码中的&lt;改为<,&amp;改为&)

完整修复后的代码

#include <stdio.h>
#include <limits.h>

typedef struct {
    int tL;          // 到达时间
    int rafaga;      // Burst时间
    char id;         // 进程ID
    int tE;          // 等待时间
    int tP;          // 周转时间
} process;

int main(int argc, char** argv) {
    int n = 3;
    int i, completed = 0, selected;
    process p[n], aux;
    char id[] = {'A','B','C','D','E','F'};
    int current_time = 0;

    // 输入进程信息
    for(i=0; i<n; i++) {
        printf("Process burst %d: ", i);
        scanf("%d", &p[i].rafaga);
        printf("Arrival time %d: ", i);
        scanf("%d", &p[i].tL);
        p[i].id = id[i];
        p[i].tE = 0;
        p[i].tP = 0;
    }

    // 按到达时间预排序
    for (i=0; i<n; i++) {
        for(j=i+1; j<n; j++) {
            if(p[i].tL > p[j].tL) {
                aux = p[j];
                p[j] = p[i];
                p[i] = aux;
            }
        }
    }

    // 非抢占式SJF调度
    while (completed < n) {
        selected = -1;
        int min_burst = INT_MAX;
        // 筛选已到达的最短burst进程
        for (i=0; i<n; i++) {
            if (p[i].tL <= current_time && p[i].rafaga > 0 && p[i].rafaga < min_burst) {
                min_burst = p[i].rafaga;
                selected = i;
            }
        }

        if (selected == -1) {
            current_time++;
            continue;
        }

        // 执行进程并计算时间
        current_time += p[selected].rafaga;
        p[selected].tP = current_time - p[selected].tL;
        p[selected].tE = p[selected].tP - p[selected].rafaga;
        p[selected].rafaga = 0;
        completed++;
    }

    // 格式化输出结果
    printf(" ID | Turnaround | Wait Time \n");
    printf("----|------------|-----------\n");
    for(i=0; i<n; i++) {
        printf(" %c  |     %d      |     %d     \n", p[i].id, p[i].tP, p[i].tE);
    }

    return 0;
}

测试验证

比如输入以下进程信息:

Process burst 0: 3
Arrival time 0: 0
Process burst 1: 2
Arrival time 1: 1
Process burst 2: 1
Arrival time 2: 2

输出结果会符合非抢占式SJF的预期:

ID | Turnaround | Wait Time 
----|------------|-----------
 A  |     3      |     0     
 C  |     2      |     1     
 B  |     5      |     3     

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:56:58