多级反馈队列调度算法模拟实现

实验一 多级反馈队列调度算法

在这里插入图片描述

一. 主要实现方法和代码介绍

​ 1.编写进程类,其只包含所需的运行时间和进程编号两个属性,还有一个运行方法,此方法就是将所需的运行时间属性减去.传入的运行时间.

​ 2.创建进程函数:创建maxp个进程,(应该不超过10,在此创建九个,即暂时不进行进程队列越界处理),其运行时间符合均值为0,方差为20的高斯分布,并取整取绝对之后所得到的值, (此处是为了全自动创建进程),进程号自己自增. 在创建进程时,使用mutex库将每一个queue 加锁和解锁,以实现互斥访问.

​ 3.运行函数. 主要的算法函数. 首先判断队列非空,即进入运行,一级队列非空时,优先运行第一级队列,一级队列空后,才检差后几级队列. 但是后几级队列每一次执行后,都重新检查一级队列是否非空.具体实现是:if(一级队列非空) { while(一级队列非空){ 运行}} ;而高级别不执行while. 其次,当一次执行没有执行完,则立即放入下一级队列,每次写入都加锁.

二. 程序流程图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B8AyJRjO-1647856457764)(C:\Users\51330\AppData\Roaming\Typora\typora-user-images\image-20211009101816266.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S14kJ5Lg-1647856457765)(C:\Users\51330\AppData\Roaming\Typora\typora-user-images\image-20211009101923526.png)]

三. 程序代码

#include 
#include 
//随机数
#include 
#include 
#include 
#include 
#include 

#define T 10
#define Qsize 10
using namespace std;
mutex mym1;
mutex mym2;
mutex mym3;
mutex mym4;
int ALLP = 0;
int CPUTIME = 0;
int information = 0;
class Process
{
public:
    int RUNTIME;
    int PNUM;
    void run(int runt);
};
void Process::run(int rt)
{
    cout << CPUTIME << ":" << ends;
    if (rt >= RUNTIME)
    {
        RUNTIME = 0;
        cout << "进程" << PNUM << "已运行完." << endl;
        CPUTIME += rt;
    }
    else
    {
        RUNTIME -= rt;
        cout << "进程" << PNUM << "已运行" << rt << "时,还需" << RUNTIME << "时即可运行完." << endl;
        CPUTIME += rt;
    }
}
queue<Process> q1, q2, q3, q4;
void createProcess(int maxp)
{
    // 从epoch(1970年1月1日00:00:00 UTC)开始经过的纳秒数,unsigned类型会截断这个值
    unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
    std::default_random_engine generator(seed);
    // 第一个参数为高斯分布的平均值,第二个参数为标准差
    std::normal_distribution<double> distribution(0.0, 20.0);
    //   for (int i = 0; i < 10; ++i)
    //     std::cout << distribution(generator) << std::endl;
    for (int i = 1; i <= maxp; i++)
    {
        Process c1;
        c1.RUNTIME = std::abs((int)distribution(generator));
        c1.PNUM = ALLP++;
        mym1.lock();
        q1.push(c1);
        mym1.unlock();
        cout << "已创建" << ALLP - 1 << "号进程,需要" << c1.RUNTIME << "时来完成." << endl;
    }
    information++;
}
void running()
{
    int performed = 0;
    while (true)
    {
        // if (!q1.empty() || !q2.empty() || !q3.empty() || !q4.empty())
        {
            if (!q1.empty())
            {
                while (!q1.empty())
                {
                    Process c1 = q1.front();
                    mym1.lock(); // lock
                    q1.pop();
                    mym1.unlock();
                    c1.run(T);
                    if (c1.RUNTIME != 0)
                    {
                        if (q2.size() < Qsize)
                        {
                            mym2.lock(); //加锁
                            q2.push(c1);
                            mym2.unlock();
                        }
                        else
                        {
                            暂时没管队列已满时的卡死状态
                        }
                    }
                }
            }
            else if (!q2.empty())
            {
                Process c2 = q2.front();
                mym2.lock();
                q2.pop();
                mym2.unlock();
                c2.run(2 * T);
                if (c2.RUNTIME != 0)
                {
                    if (q3.size() < Qsize)
                    {
                        mym3.lock();
                        q3.push(c2);
                        mym3.unlock();
                    }
                    else
                    {
                        暂时没管队列已满时的卡死状态
                    }
                }
                if (!performed)
                {
                    createProcess(9);
                    performed = 1;
                }
            }
            else if (!q3.empty())
            {
                Process c3 = q3.front();
                mym3.lock();
                q3.pop();
                mym3.unlock();
                c3.run(4 * T);
                if (c3.RUNTIME != 0)
                {
                    if (q4.size() < Qsize)
                    {
                        mym4.lock();
                        q4.push(c3);
                        mym4.unlock();
                    }
                    else
                    {
                        暂时没管队列已满时的卡死状态
                    }
                }
            }
            else if (!q4.empty())
            {
                Process c4 = q4.front();
                mym4.lock();
                q4.pop();
                mym4.unlock();
                c4.run(8 * T);
                if (c4.RUNTIME != 0)
                {
                    if (q4.size() < Qsize)
                    {
                        mym4.lock();
                        q4.push(c4);
                        mym4.unlock();
                    }
                    else
                    {
                        暂时没管队列已满时的卡死状态
                    }
                }
            }
            else
            {
                cout << CPUTIME << ":当前时刻所有进程已运行完." << endl;
                while (!q1.empty() || !q2.empty() || !q3.empty() || !q4.empty())
                {
                    break;
                }
                if (information == 2)
                    break;
            }           // }
        }
    }
}
int main()
{
    // thread t1(createProcess, 9);
    createProcess(9);
    thread t2(running);
    // t1.join();
    t2.join();
    return 0;
}

四. 运行结果

多级反馈队列调度算法模拟实现_第1张图片

五.结果分析

​ 观察上方运行结果即可得到:

  1. 先进行创建进程,创建了九个进程. 而后当一级队列运行完成后,再次创建了九个进程,后面重新从一级队列开始运行. 运行完后,才运行下级队列的1~7号进程.

    故可以看出,一级队列最高优先级实现成功.

  2. 代码缺陷分析:

    • 创建进程和运行不能同步进行. 虽然尝试实现创建两个线程,让运行函数和创建进程的函数分开运行,通过对共享变量(共享内存通信)的修改通知不同的进程运行,但总是进入死循环,尝试失败
    • 没有按照老师上课讲得PCB的大部分信息来创建进程, 而是偷懒只考虑自己的模拟需求,只有运行时间和进程号两个属性.

. 运行完后,才运行下级队列的1~7号进程.

故可以看出,一级队列最高优先级实现成功.

  1. 代码缺陷分析:

    • 创建进程和运行不能同步进行. 虽然尝试实现创建两个线程,让运行函数和创建进程的函数分开运行,通过对共享变量(共享内存通信)的修改通知不同的进程运行,但总是进入死循环,尝试失败
    • 没有按照老师上课讲得PCB的大部分信息来创建进程, 而是偷懒只考虑自己的模拟需求,只有运行时间和进程号两个属性.

你可能感兴趣的:(计算机操作系统,c++)