操作系统 实验 进程调度算法

实验思路

时间片轮转(RR)调度算法是专门为分时系统设计的。它类似于 FCFS调度,但是增加了抢占以切换进程。

该算法中,将一个较小时间单元定义为时间量或时间片。时间片的大小通常为 10~100ms。就绪队列作为循环队列。CPU 调度程序循环整个就绪队列,为每个进程分配不超过一个时间片的 CPU。

为了实现 RR 调度,我们再次将就绪队列视为进程的 FIFO 队列。新进程添加到就绪队列的尾部。CPU 调度程序从就绪队列中选择第一个进程,将定时器设置在一个时间片后中断,最后分派这个进程。

接下来,有两种情况可能发生。进程可能只需少于时间片的 CPU 执行。对于这种情况,进程本身会自动释放 CPU。调度程序接着处理就绪队列的下一个进程。否则,如果当前运行进程的 CPU 执行大于一个时间片,那么定时器会中断,进而中断操作系统。然后,进行上下文切换,再将进程加到就绪队列的尾部,接着 CPU 调度程序会选择就绪队列内的下一个进程。

采用非常公平的处理机分配方式,即让就绪队列上的每个进程每次仅运行一个时间片,本来使用就绪队列来做的,刚开始没有注意,没有使用就绪队列来做,使用容器vector来做,根据时间的递增,来逐渐选择要执行的进程,当出现某一进程完成时,就从每一使用时间最短的进程挑选,并执行,能够实现RR调度,对每个进程来说都比较公平

代码实现

/**
 * @file rp.c++
 * @author Luke Tebo (you@domain.com)
 * @brief
 * @version 0.1
 * @date 2022-05-01
 *
 * @copyright Copyright (c) 2022
 *
 * 算法选择:RR 时间片轮转算法
 */
#include <iostream>
#include <stdio.h>
#include <vector>
#include <queue>
#include <windows.h>
typedef unsigned int uint32;
/*常量和状态定义*/

class PCB
{
private:
    uint32 pid;              // 进程标识符
    uint32 arrive_time;      // 到达时间
    uint32 serve_time;       // 服务时间
    uint32 use_time;         // 已用时间
    uint32 finish_time;      // 完成时间
    uint32 turn_around_time; // 周转时间
    uint32 status;           // 进程状态
public:
    PCB(){};
    ~PCB(){};
    void init(uint32 pid, uint32 arrive_time, uint32 serve_time)
    {
        this->pid = pid;
        this->arrive_time = arrive_time;
        this->serve_time = serve_time;
        this->use_time = 0;
        this->finish_time = 0;
        this->turn_around_time = 0;
        this->status = 0;
    };
    uint32 get_pid()
    {
        return pid;
    };
    uint32 get_arrive_time()
    {
        return arrive_time;
    };
    uint32 get_finish_time()
    {
        return finish_time;
    };
    uint32 get_turn_around_time()
    {
        return turn_around_time;
    };
    uint32 get_serve_time()
    {
        return serve_time;
    };
    uint32 get_status()
    {
        return status;
    };
    uint32 get_use_time()
    {
        return use_time;
    };
    void set_status(uint32 status)
    {
        this->status = status;
    };
    void set_finish_time(uint32 finish_time)
    {
        this->finish_time = finish_time;
    }
    void set_turn_around_time(uint32 turn_around_time)
    {
        this->turn_around_time = turn_around_time;
    }
    void set_use_time(uint32 use_time)
    {
        this->use_time = use_time;
    }
};
class USE
{
private:
    uint32 index;
    uint32 time;

public:
    USE(){};
    ~USE(){};
    void init(uint32 index, uint32 time)
    {
        this->index = index;
        this->time = time;
    };
    uint32 get_index()
    {
        return index;
    };
    uint32 get_time()
    {
        return time;
    };
    void set_index(uint32 index)
    {
        this->index = index;
    };
    void set_time(uint32 time)
    {
        this->time = time;
    };
};
// 初始化进程信息
void init_process(std::vector<PCB> &process_list, uint32 process_num)
{
    uint32 i = 0;
    uint32 pid = 0;
    uint32 arrive_time = 0;
    uint32 finish_time = 0;
    for (i = 0; i < process_num; i++)
    {
        printf("请输入进程%d的到达时间和完成时间: ", i);
        scanf("%d %d %d", &pid, &arrive_time, &finish_time);
        process_list.push_back(PCB());
        process_list[i].init(pid, arrive_time, finish_time);
    }
}
// 打印进程信息
void print_process(std::vector<PCB> &process_list)
{
    int size = process_list.size();
    std::cout << "进程ID 到达时间 服务时间 完成时间 周转时间 已用时间" << std::endl;
    for (int i = 0; i < size; i++)
    {
        printf("  %d\t  %d\t  %d\t    %d\t    %d\t    %d\n", process_list[i].get_pid(), process_list[i].get_arrive_time(), process_list[i].get_serve_time(), process_list[i].get_finish_time(), process_list[i].get_turn_around_time(), process_list[i].get_use_time());
    }
}
// RP算法
void RP(std::vector<PCB> &process_list)
{
    uint32 q = 0;
    printf("输入时间片大小:");
    scanf("%d", &q);
    uint32 time = 0; // 初始化时间
    uint32 count = 0;
    // // std::vector<uint32> process_serve_time(process_list.size(), 0); // 进程服务时间
    // if(process_list[0].get_arrive_time() == 0){
    //     process_list[0].set_status(1);
    // }
    boolean flag = false;
    boolean flag2 = false;
    uint32 min_time = process_list[0].get_use_time();
    std::queue<PCB> prepare_process_queue; // 就绪队列
    while (count < process_list.size())
    {
        uint32 i = 0;
        std::vector<int> min_time_index(0);      // 存取进程完成之后最小进程的use_time
        std::vector<int> min_time_index_temp(0); // 存取进程完成之后use_time最小的进程的下标
        //  为每一次进程调度做准备 设置这个进程的状态,是否能够执行
        if (count == 0)
        {
            for (i = 0; i < process_list.size(); i++)
            {
                if (time >= process_list[i].get_arrive_time() && process_list[i].get_status() == 0 && (i == time || i == time % process_list.size()))
                {
                    printf("first %d\n", i);
                    flag = true;
                    // printf("%c\n", flag);
                    process_list[i].set_status(1); // 设置为就绪状态 可以运行
                }
            }
        }
        else if (count > 0)
        {
            for (i = 0; i < min_time_index.size(); i++)
            {
                min_time_index[i] = 0;
            }
            for (i = 0; i < min_time_index_temp.size(); i++)
            {
                min_time_index_temp[i] = 0;
            }

            for (i = 0; i < process_list.size(); i++)
            {

                if (process_list[i].get_status() != 2)
                {
                    // printf("second %d\n", i + 1);
                    min_time_index.push_back(process_list[i].get_use_time());
                    min_time_index_temp.push_back(i);
                    // flag2 = true;
                    // process_list[i + 1].set_status(1);
                }
            }

            std::cout << "满足条件的下标: " << std::endl;
            for (i = 0; i < min_time_index.size(); i++)
            {
                std::cout << min_time_index[i] << " ";
            }
            std::cout << std::endl;
            for (i = 0; i < min_time_index.size(); i++)
            {
                for (int j = i; j < min_time_index.size(); j++)
                {
                    if (min_time_index[i] > min_time_index[j])
                    {
                        uint32 temp = min_time_index[i];
                        min_time_index[i] = min_time_index[j];
                        min_time_index[j] = temp;

                        uint32 temp_index = min_time_index_temp[i];
                        min_time_index_temp[i] = min_time_index_temp[j];
                        min_time_index_temp[j] = temp_index;
                    }
                }
            }

            process_list[min_time_index_temp[0]].set_status(1); // 设置为就绪状态

            printf("third %d\n", min_time_index_temp[0]);
        }

        // 如果当前没有进程被标记为就绪状态,则继续执行下一个时间片

       
        // 通过时间片 开始执行
        for (i = 0; i < process_list.size(); i++)
        {
            // 如果就绪状态就运行
            if (process_list[i].get_status() == 1 && process_list[i].get_status() != 2)
            {
                process_list[i].set_use_time(process_list[i].get_use_time() + q);
                if (process_list[i].get_use_time() == process_list[i].get_serve_time())
                {
                    process_list[i].set_status(2); // 设置为完成状态
                    process_list[i].set_finish_time(time + 1);
                    count++;
                    process_list[i].set_turn_around_time(time + 1 - process_list[i].get_arrive_time());
                }
                else
                {
                    process_list[i].set_status(0); // 阻塞
                }
            }
        }
        time++;
        printf("------%d------\n", time);
        print_process(process_list);

       
        flag = false;
        flag2 = false;
        Sleep(80);
    }
}

int main()
{

    std::vector<PCB> pcb_list;
    init_process(pcb_list, 5);
    RP(pcb_list);
    print_process(pcb_list);

    return 0;
}

结果展示

fair调度策略 spark 调度算法rr_fair调度策略 spark

fair调度策略 spark 调度算法rr_#include_02

fair调度策略 spark 调度算法rr_#include_03