目录
前言
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的讲解就到这里了,希望对大家有帮助。如果对大家有帮助,希望大家可以给我一个点赞、关注、收藏,这对我很重要,谢谢大家!