ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

操作系统-作业调度算法设计

2021-12-20 15:30:52  阅读:176  来源: 互联网

标签:processes 操作系统 process 调度 int 算法 pa time select


作业调度算法设计

1.先来先服务调度算法(实现)
2.短作业优先调度算法(实现,但可能有漏洞)
3.最高响应比调度算法(实现,但可能有漏洞)
4.最短剩余时间调度算法(抢占式,实现,但可能有漏洞)

输入
数据存放于 data.txt 文件中,每列分别对应进程名进程到达时间进程运行时间

J1 8:00 30.0
J2 8:20 5.0
J3 8:30 15.0

代码详情

#define _CRT_SECURE_NO_WARNINGS
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct
{
    char pname[10];         // 进程名 = input
    float pid;              // 进程id = input
    char arrival[10];       // 到达时刻 = input
    float time_arrival;     // 到达时间 = time2int(arrival)
    float time_run;         // 运行时间 = input 单位:分钟
    float time_start;       // 开始时间 According to the reslut of the algorithm
    float time_finish;      // 完成时间 According to the reslut of the algorithm
    float time_remaining;   // 剩余时间
    char begin[10];         // 开始时刻 = "str(time_start/60):str(time_start%60)" use ecvt() or gcvt().
    char finish[10];        // 完成时刻 = "str(time_finish/60):str(time_finish%60)"
    float tar;              // 周转时间 Turnaround time = time_finish - ta
    float tarw;             // 带权周转时间 Turnaround time with weight = tar / tr
    float rp;               // 响应比
} process;

typedef struct
{
    int len;
    float ava_tar, ava_tarw; // 平均周转时间、平均带权周转时间
    process *processes;
} process_array;

void print_process_array(process_array *pa)
{
    printf("====================================================\
==================================================================\n");
    printf("\t进程名\t到达时间\t运行时间\t开始时间\t完成时间\t周转时间\t带权周转时间\n");
    for (int i = 0; i < pa->len; i++)
    {
        printf("----------------------------------------------------\
------------------------------------------------------------------\n");
        printf("\t %s\t %s\t\t %-.2f\t\t %s\t\t %s\t\t %-.2f\t\t   %-.2f\n",
               pa->processes[i].pname,
               pa->processes[i].arrival,
               pa->processes[i].time_run,
               pa->processes[i].begin,
               pa->processes[i].finish,
               pa->processes[i].tar,
               pa->processes[i].tarw);
    }
    printf("----------------------------------------------------\
------------------------------------------------------------------\n");
    printf("\t平均周转时间:\t\t\t\t\t\t\t\t %.2f\n", pa->ava_tar);
    printf("----------------------------------------------------\
------------------------------------------------------------------\n");
    printf("\t平均带权周转时间:\t\t\t\t\t\t\t\t\t   %.2f\n", pa->ava_tarw);
    printf("====================================================\
==================================================================\n");
}

// 释放内存
void free_process_array(process_array **pa)
{
    free((*pa)->processes);
    free(*pa);
    *pa = NULL;
}

int time2int(char *time)
{
    // 输入形如:xx:xx 格式的时间,输出分钟型的时间
    int len_char = sizeof(time);
    char t[10];
    for (int i = 0; i < len_char; i++)
    {
        t[i] = time[i];
    }
    char min[4];
    for (int i = 0; i < len_char; i++)
    {
        if (time[i] == ':')
        {
            int k = 0;
            while (time[k + i + 1] != '\0')
            {
                min[k] = time[k + i + 1];
                k++;
            }
            min[k] = '\0';
            break;
        }
    }
    char *hour = strtok(t, ":");
    return atol(hour) * 60 + atol(min); // 字符型转整型
}

char *int2time(int time, char *buf)
{
    int hour = (time / 60) % 24;
    int minute = time % 60;
    if (sprintf(buf, "%02d:%02d", hour, minute) < 0)
        return NULL;
    return buf;
}

// 初始化参数
void process_init(process_array *pa)
{
    for (int i = 0; i < pa->len; i++)
    {
        pa->processes[i].time_arrival = time2int(pa->processes[i].arrival);
        pa->processes[i].time_remaining = pa->processes[i].time_run;
        pa->processes[i].time_start = -1; // 代表进程未开始运行
        pa->processes[i].tar = -1; // 代表周转时间未计算
        pa->processes[i].tarw = -1; // 代表带权周转时间未计算
        pa->processes[i].rp = -1; // 代表响应比未计算
    }
}

// 到达时间排序,先到先排
void sort_by_arrive_time(process_array *pa)
{
    for (int i = 0; i < pa->len; i++)
    {
        for (int j = i + 1; j < pa->len; j++)
        {
            if (pa->processes[j].time_arrival < pa->processes[i].time_arrival)
            {
                process tmp = pa->processes[i];
                pa->processes[i] = pa->processes[j];
                pa->processes[j] = tmp;
            }
        }
    }
}

// 短作业优先
void shortest_job_first(process_array *pa)
{
    float current_time = -1; // -1 表示未初始化
    for (int i = 0; i < pa->len; i++)
    {
        if (current_time == -1)
        {
            current_time = pa->processes[i].time_arrival;
        }

        // 选择当前时刻内最短的作业
        int select = 0;
        for (int j = 0; j < pa->len; j++)
        {
            if (pa->processes[j].time_finish != 0)
            {
                continue; // 作业已经完成
            }

            if (pa->processes[j].time_arrival > current_time)
            {
                break; // 时间没到
            }

            if (pa->processes[j].time_run < pa->processes[select].time_run)
            {
                select = j;
            }
        }

        // 执行选择的任务
        pa->processes[select].time_start = current_time;
        int2time(pa->processes[select].time_start, pa->processes[select].begin);
        pa->processes[select].time_finish = pa->processes[select].time_start + pa->processes[select].time_run;
        int2time(pa->processes[select].time_finish, pa->processes[select].finish);
        pa->processes[select].tar = pa->processes[select].time_finish - pa->processes[select].time_arrival;
        pa->processes[select].tarw = pa->processes[select].tar / pa->processes[select].time_run;
        current_time = pa->processes[select].time_finish;
    }
}

// 响应比计算
float response_ratio(process process, int start_time)
{
    /* 响应比 = ((开始运行时间 - 作业到达时间) + 运行时间) / 运行时间 */
    return ((start_time - process.time_arrival) + process.time_run) / process.time_run;
}

// 最高响应比优先
// 用于作业/进程调度
// 非抢占式的算法,因此只有当前运行的作业/进程主动放弃处理器时,才需要调度,才需要计算响应比
void highest_response_ratio_priority(process_array *pa, char* start)
{
    int work_time = time2int(start);
    float max_rp;
    for (int m = 0; m < pa->len; m++)
    {
        max_rp = 0;
        int i = 0;
        // 统计有多少个作业/进程在某次调度开始前到达
        for (int n = 0; n < pa->len; n++)
        {
            if (pa->processes[n].time_arrival <= work_time)
            {
                if (pa->processes[n].rp != 0)
                {
                    // 计算这些作业的响应比,找出最大的
                    pa->processes[n].rp = response_ratio(pa->processes[n], work_time);
                    if (pa->processes[n].rp > max_rp)
                    {
                        max_rp = pa->processes[n].rp;
                        i = n;
                    }
                    continue;
                }
            }
            else
                break;
        }
        // 响应比最大的开始运行
        pa->processes[i].time_start = work_time;
        int2time(pa->processes[i].time_start, pa->processes[i].begin);
        pa->processes[i].time_finish = pa->processes[i].time_start + pa->processes[i].time_run;
        int2time(pa->processes[i].time_finish, pa->processes[i].finish);
        pa->processes[i].tar = pa->processes[i].time_finish - pa->processes[i].time_arrival;
        pa->processes[i].tarw = pa->processes[i].tar / pa->processes[i].time_run;
        work_time = pa->processes[i].time_finish; // 下一次进行作业调度时间为当前作业运行完成时刻
        pa->processes[i].rp = 0; // 完成作业
    }
}

// 先来先服务
void first_come_first_service(process_array *pa)
{
    float current_time = -1; // -1 表示未初始化
    for (int i = 0; i < pa->len; i++)
    {
        if (current_time == -1)
        {
            current_time = pa->processes[i].time_arrival;
        }

        pa->processes[i].time_start = current_time;
        int2time(pa->processes[i].time_start, pa->processes[i].begin); // 转成字符串
        pa->processes[i].time_finish = pa->processes[i].time_start + pa->processes[i].time_run;
        int2time(pa->processes[i].time_finish, pa->processes[i].finish);
        pa->processes[i].tar = pa->processes[i].time_finish - pa->processes[i].time_arrival;
        pa->processes[i].tarw = pa->processes[i].tar / pa->processes[i].time_run;
        current_time = pa->processes[i].time_finish;
    }
}

// 最短剩余优先(抢占式)
void shortest_residue_time_fist(process_array *pa)
{
    int curren_time = 0;
    curren_time = pa->processes[0].time_arrival;

    while (1)
    {
        int break_flag = 1;
        for (int i = 0; i < pa->len; i++)
        {
            if (pa->processes[i].time_remaining != 0)
            {
                break_flag = 0;
            }
        }
        if (break_flag == 1)
        {
            break;
        }

        // 找出最短剩余时间的进程
        int select = 0;
        for (int i = 0; i < pa->len; i++)
        {
            if (curren_time < pa->processes[i].time_arrival)
            {
                break;
            }

            if (pa->processes[i].time_remaining == 0)
            {
                continue;
            }

            if (pa->processes[i].time_remaining < pa->processes[select].time_remaining || pa->processes[select].time_remaining == 0)
            {
                select = i;
                break;
            }
        }

        // 抢占运行
        if (pa->processes[select].time_start == -1)
        {
            pa->processes[select].time_start = curren_time;
            int2time(pa->processes[select].time_start, pa->processes[select].begin); // 转成字符串
        }
        pa->processes[select].time_remaining--;
        curren_time++;
        if (pa->processes[select].time_remaining == 0)
        {
            pa->processes[select].time_finish = curren_time;
            int2time(pa->processes[select].time_finish, pa->processes[select].finish); // 转成字符串
            pa->processes[select].tar = pa->processes[select].time_finish - pa->processes[select].time_arrival;
            pa->processes[select].tarw = (float)pa->processes[select].tar / pa->processes[select].time_run;
        }
    }
}

// 求平均周转时间、平均带权周转时间
void compute_average(process_array *pa)
{
    float sum_tar = 0, sum_tarw = 0;
    for (int i = 0; i < pa->len; i++)
    {
        sum_tar += pa->processes[i].tar;
        sum_tarw += pa->processes[i].tarw;
    }
    pa->ava_tar = sum_tar / pa->len;
    pa->ava_tarw = sum_tarw / pa->len;
}

// 从文件中读取初始数据
process_array *read_process_array_from_file(const char *path)
{
    FILE *fp = fopen(path, "r");
    if (fp == NULL)
    {
        return NULL;
    }

    // 申请一个进程队列空间
    process_array *pa = calloc(sizeof(process_array), 1);
    char line[256];
    while (fgets(line, sizeof(line), fp) != NULL)
    {
        pa->len += 1;
        process *tmp = calloc(sizeof(process), pa->len);
        memcpy(tmp, pa->processes, sizeof(*tmp) * (pa->len - 1));
        free(pa->processes);
        pa->processes = tmp;
        // 分别读入进程名、进程到达时间、进程运行时间
        if (sscanf(line, "%s %s %f", pa->processes[pa->len - 1].pname, pa->processes[pa->len - 1].arrival, &pa->processes[pa->len - 1].time_run) != 3)
        {
            free(tmp);
        }
    }

    fp = NULL;

    return pa;
}

int run()
{
    process_array *pa = read_process_array_from_file("data.txt");
    if (pa == NULL)
    {
        printf("%s\n", strerror(errno));
        return 1;
    }
    // 初始化各参数
    process_init(pa);
    // 根据到达时间排序
    sort_by_arrive_time(pa);
    int algorithm;
    printf("====================================================\
==================================================================\n\
==============================================数据已载入,请选择算法===\
===============================================\n\
\t1.先来先服务调度算法, 2.短作业优先调度算法, 3.最高响应比调度算法, 4.最短剩余时间调度算法, 5.退出程序\n");
    printf("====================================================\
==================================================================\n");
    scanf("%d", &algorithm);
    system("cls");

    printf("====================================================\
==================================================================\n");

    switch (algorithm)
    {
    case 1:
        printf("\t\t\t\t\t先来先服务调度算法\n");
        first_come_first_service(pa);
        break;
    case 2:
        printf("\t\t\t\t\t短作业优先调度算法\n");
        shortest_job_first(pa);
        break;
    case 3:
        printf("\t\t\t\t\t最高响应比调度算法\n");
        printf("\t请输入开始时间:");
        char* start[10];
        scanf("%s", &start);
        printf("\n");
        highest_response_ratio_priority(pa, start);
        break;
    case 4:
        printf("\t\t\t\t\t最短剩余时间调度算法\n");
        shortest_residue_time_fist(pa);
        break;
    case 5:
        return 1;
        break;
    default:
        printf("您的选择不在范围内,请从以下算法中选择:\n");
        // 释放内存
        free_process_array(&pa);
        return 0;
        break;
    }
    compute_average(pa);
    print_process_array(pa);
    // 释放内存
    free_process_array(&pa);
    return 0;
}

int main()
{
    while (1)
    {
        if(run() == 1)
            break;
    }
    return 0;
}

输出
选择算法界面

======================================================================================================================
==============================================数据已载入,请选择算法==================================================
        1.先来先服务调度算法, 2.短作业优先调度算法, 3.最高响应比调度算法, 4.最短剩余时间调度算法, 5.退出程序
======================================================================================================================

结果显示界面

======================================================================================================================
                                        最短剩余时间调度算法
======================================================================================================================
        进程名  到达时间        运行时间        开始时间        完成时间        周转时间        带权周转时间
----------------------------------------------------------------------------------------------------------------------
         J1      8:00            30.00           08:00           08:35           35.00             1.17
----------------------------------------------------------------------------------------------------------------------
         J2      8:20            5.00            08:20           08:25           5.00              1.00
----------------------------------------------------------------------------------------------------------------------
         J3      8:30            15.00           08:35           08:50           20.00             1.33
----------------------------------------------------------------------------------------------------------------------
        平均周转时间:                                                           20.00
----------------------------------------------------------------------------------------------------------------------
        平均带权周转时间:                                                                         1.17
======================================================================================================================
======================================================================================================================
==============================================数据已载入,请选择算法==================================================
        1.先来先服务调度算法, 2.短作业优先调度算法, 3.最高响应比调度算法, 4.最短剩余时间调度算法, 5.退出程序
======================================================================================================================

19 guan老师课程学生

标签:processes,操作系统,process,调度,int,算法,pa,time,select
来源: https://blog.csdn.net/Meet_Unknown/article/details/122020021

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有