带到达时间的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会报错) - 初始化结构体成员,避免垃圾值干扰计算
- 修正代码中转义的
<和&符号(原代码中的<改为<,&改为&)
完整修复后的代码
#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
相关产品推荐
相关产品推荐

