操作系统之如何使用C语言完成SFJ和SRTJ,并完成他的甘特图

目录

前言

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

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值