目录
前言
SFJ
SRTJ
结束语
前言
不知不觉已经写博客一个月了,前段时间因为学业上的一些原因咕咕咕了,今天我又回来了。今天我给大家带来的是C语言代码完成的SFJ和SRTJ,并且带大家描述他的甘特图。如果有对SFJ和SRTJ不了解的小伙伴可以翻博主曾经的文章,那里有详细的讲解。
SFJ
讲解
我们在代码中,需要传入进程的编号process、到达时间arrive、服务时间serve、进程数量pro,我这里还传入一个参数choice代表选择默认数据还是自行输入的数据,小伙伴们可以根据实际情况进行删减。
SFJ的实现非常简单,只需要在每次有进程到达时,判断当前各进程在就绪队列中进程的服务时间长短并进行排序即可,然后依次输出就好。
我在完成代码时,使用了冒泡排序,其实可以用其他排序,时间复杂度更低,效率更高,因为完成时我们用到的数据量不大,所以就用了冒泡,实现起来比较简单(doge)。
其中第一个if是用来判断到达时间的先后,对他们进入就绪队列的前后进行判断。第二个if是对两个同时进入就绪队列的进程,用他们的服务时间来判断谁先谁后,达到SFJ的思想。
代码
下面上代码
void SJF(int process[],int arrive[],int serve[],int pro,int choice){double wait = 0.0;//计算平均等待时间printf("当前SJF的数据如下:\n进程编号:\t\t到达时间:\t\t服务时间:\t\t\n");for(int i = 0;i<pro;i++){printf("P%d\t\t\t%d\t\t\t%d\t\t\t\n",process[i],arrive[i],serve[i]);}printf("------------------------------------------------------------------------------------\n");for(int i = 0;i<pro;i++){for(int j = 0;j<pro - i - 1;j++){int temp;if(arrive[j]>arrive[j+1]){temp = arrive[j+1];arrive[j+1] = arrive[j];arrive[j] = temp;temp = process[j+1];process[j+1] = process[j];process[j] = temp;temp = serve[j+1];serve[j+1] = serve[j];serve[j] = temp;}if(arrive[j]==arrive[j+1]){if(serve[j]>serve[j+1]){temp = arrive[j+1];arrive[j+1] = arrive[j];arrive[j] = temp;temp = process[j+1];process[j+1] = process[j];process[j] = temp;temp = serve[j+1];serve[j+1] = serve[j];serve[j] = temp;}}}}int end = 0,start = 0;printf("\n甘特图描述如下:\n");for(int i = 0;i<pro;i++){//从当前进程开始,如果进程已经到达,则比较服务时间长短,服务时间短的先for(int j = i;j<pro-1;j++){if(arrive[j] <= end){for(int kk = i;kk < pro;kk++){//进程还没到达,就退出比较if(arrive[kk] > end){break;}if(serve[j] > serve[kk]){int temp;temp = arrive[j+1];arrive[j+1] = arrive[j];arrive[j] = temp;temp = process[j+1];process[j+1] = process[j];process[j] = temp;temp = serve[j+1];serve[j+1] = serve[j];serve[j] = temp;}}}}end = end + serve[i];wait = wait + start - arrive[i];printf("现在运行的进程是P%d\t\t进程开始的时间是%d\t\t进程的结束时间是%d\t\t\n",process[i],start,end);start = end;}wait = wait / pro;printf("平均等待时间是:%.3lf\n",wait);printf("------------------------------------------------------------------------------------\n");
}
结果
接下来是结果,我们这里使用默认数据,大家也可以用自行输入的数据进行测试。
SRTJ
讲解
我们依旧使用了process、arrive、serve、pro、choice这五个参数,如果有跳着看不明白含义的小伙伴可以在SJF的开头找到解释。这里我们仍然先按照SJF的思路,把进程按照到达时间和服务时间排序。但是需要在进行算法时,注意SRTJ的重点:最短剩余时间,否则最终得出的顺序将会有错误,甘特图也会有错。
代码
接下来是大家期待的代码
void SRTJ(int process[],int arrive[],int serve[],int pro,int choice){double wait = 0.0;//计算平均等待时间printf("当前SRTJ的数据如下:\n进程编号:\t\t到达时间:\t\t服务时间:\t\t\n");for(int i = 0;i<pro;i++){printf("P%d\t\t\t%d\t\t\t%d\t\t\t\n",process[i],arrive[i],serve[i]);}printf("------------------------------------------------------------------------------------\n");for(int i = 0;i<pro;i++){for(int j = 0;j<pro - i - 1;j++){int temp;if(arrive[j]>arrive[j+1]){temp = arrive[j+1];arrive[j+1] = arrive[j];arrive[j] = temp;temp = process[j+1];process[j+1] = process[j];process[j] = temp;temp = serve[j+1];serve[j+1] = serve[j];serve[j] = temp;}if(arrive[j]==arrive[j+1]){if(serve[j]>serve[j+1]){temp = arrive[j+1];arrive[j+1] = arrive[j];arrive[j] = temp;temp = process[j+1];process[j+1] = process[j];process[j] = temp;temp = serve[j+1];serve[j+1] = serve[j];serve[j] = temp;}}}}int n = pro;int currentTime = 0;float waitTime[pro];float turnaroundTime[pro];int remainingTime[pro];int completed = 0;int startTime[pro];for(int i = 0; i < n; ++i) startTime[i] = -1;//初始化剩余时间数组for(int i = 0; i < n; ++i) {remainingTime[i] = serve[i];}while(completed != n) {int next = -1,preNext[Max_Size],num = 0;float shortestRemaining = -1;for(int i = 0; i < n; ++i) {if(arrive[i] <= currentTime && remainingTime[i] > 0) {if(startTime[i] == -1) startTime[i] = currentTime; // 进程首次执行时记录开始时间if(shortestRemaining == -1 || remainingTime[i] < shortestRemaining) {shortestRemaining = remainingTime[i];next = i;}}}preNext[num] = next;num++;if (next != -1) {remainingTime[next]--;currentTime++;if(startTime[next] != -1) {printf("现在运行的进程是P%d,开始时间是%d,结束时间是:%d\n", process[next], currentTime-1,currentTime);}if(remainingTime[next] == 0) {waitTime[next] = currentTime - arrive[next] - serve[next];turnaroundTime[next] = currentTime - arrive[next];completed++;}}else {// 没有进程可调度时,推进时间到下一个进程的到达时间for(next = 0; next < n; ++next) {if(arrive[next] > currentTime) {currentTime = arrive[next];break;}}if(next == n) break;}}for(int i = 0;i<pro;i++){wait = wait + waitTime[i];}wait = wait / pro;printf("平均等待时间是:%.3lf\n",wait);printf("------------------------------------------------------------------------------------\n");
}
结果
结束语
今天对SFJ和SRTJ的讲解就到这里了,希望对大家有帮助。如果对大家有帮助,希望大家可以给我一个点赞、关注、收藏,这对我很重要,谢谢大家!