• 循环轮转算法


    -------------------------------脑瓜疼脑瓜疼,哎呀妈呀脑瓜疼------------------------

                        多级反馈队列算法

    问题简介

    在操作系统中,多进程运行的次序是不一样的,这种时候就需要选择执行的顺序。

    在分时系统中多采用循环轮转调度算法,系统规定一个时间片,每个进程被调度的时候分得一个时间片,当这一时间片用完时,

    该进程转为就绪态并进入就绪队列末尾。这就是循环轮转算法的主要思路。

    (下面的代码只考虑P1-----P5的进程)

    简单循环轮转调度

    当CPU空闲时,选取就绪队列首元素,赋予时间片。当进程时间片用完时,就释放CPU控制权,进入就绪队列末尾,CPU控制权给

    下一个处于就绪队列首元素。

    状态图如下:

    具体思路

    本来想用队列来算的,但是考虑到指针的问题,又因为刚学了循环链表,所以考虑用循环链表来存放数据。

    (循环列表和一般链表唯一一个区别就是最后一个结点本来是p->next=NULL,现在就把头结点和尾结点相连就行,即p->next=head)

    下面是结构体的里面的内容,放入进程的名字以及需要运行的时间和等待时间

    struct pcb {
        char name[10]; //进程名称
        int need, turn; //进程运行时间和已等待时间
        struct pcb *next;
    };

    然后,给链表赋初值

    //给队列1 赋值
    struct pcb *create1() {
        int num(0);
        struct pcb *rq1 = NULL;
        struct pcb *p = NULL;
        struct pcb *t;//head头结点 p当前结点 t下一结点
        struct pcb *next;
        while(num<len1) {
            t = (struct pcb*)malloc(sizeof(struct pcb));
            if (num == 0) {
                rq1 = t;
                p = t;
            }
            else if (num == len1 - 1) {
                p->next = t;
                p = t;
                t->next = rq1;
            }
            else {
                p->next = t;
                p = t;
                t->next = NULL;
            }
            
            init(t);
            ++num;
        }
        return rq1;
    }
    
    void init(struct pcb*p) {
        cin >> p->name >> p->need >> p->turn;
    }

    在计算运行时间的时候,

    1.比如说第一个进程的运行时间小于或等于时间片的长度,所以,就把时间加上去,并将每个进程的等待时间都加上这个进程的运行时间。

    并且将正在运行的进程的need赋值为0。这样是为了将need标记为已经运行完的了,以后若再碰到就跳过这个结点。

    2.再比如说第一个进程的运行时间大于时间片的长度,就将该进程的need减去一个时间片的长度,并且将指针移到下个结点,相当于把这个结点放到队列尾部。

    再把各个进程的等待时间加上一个时间片的长度。就这样反复的循环,知道所有结点的need全部变为0的时候就跳出来。

    直接上代码吧:

    #define _CRT_SECURE_NO_WARNINGS
    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    //#define NULL 0
    #include<queue>
    using namespace std;
    const int maxn = 100;
    struct pcb {
        char name[10]; //进程名称
        int need, turn; //进程运行时间和已等待时间
        struct pcb *next;
    };
    int len1(0), len2(0); //两个进程的长度
    int clock(0); //时钟
    int time(0);//时间片大小
    int TIME; //rq1运行完的时间
    void init(struct pcb*p) {
        cin >> p->name >> p->need >> p->turn;
    }
    //给队列1 赋值
    struct pcb *create1() {
        int num(0);
        struct pcb *rq1 = NULL;
        struct pcb *p = NULL;
        struct pcb *t;//head头结点 p当前结点 t下一结点
        struct pcb *next;
        while(num<len1) {
            t = (struct pcb*)malloc(sizeof(struct pcb));
            if (num == 0) {
                rq1 = t;
                p = t;
            }
            else if (num == len1 - 1) {
                p->next = t;
                p = t;
                t->next = rq1;
            }
            else {
                p->next = t;
                p = t;
                t->next = NULL;
            }
            
            init(t);
            ++num;
        }
        return rq1;
    }
    //当运行时间小于时间片大小时候的求和函数,即将每个进程的等待时间加上当前进程运行的时间
    void sum1(struct pcb *p) {  
        struct pcb *t;
        t = p;
        while (p->next != t) {
            if (p->need != 0) {
                p->turn += t->need;
                p = p->next;
            }
            else p = p->next;;
        }
        p->turn += t->need;
    }
    
    //当运行时间大于时间片大小时候的求和函数,即将每个进程的等待时间加上当前进程运行的时间
    void sum2(struct pcb *p) { 
        struct pcb *t;
        t = p;
        while (p->next != t) {
            if (p->need != 0) {
                p->turn += time;
                p = p->next;
            }
            else p=p->next;
        }
        p->turn += time;
    }
    
    //求队列1里面各个进程运行完毕需要花费的时间
    void fun1(struct pcb *h) {
        int num, count;
        while (1) {  //最后一个的next ==NULL
            num = 0;
            count = len1;
            struct pcb *t = h; //将h赋给t
            if (t->need <= time && t->need != 0) {  //如果这个进程运行时间小于时间片且非零说明没有弄完
                clock += t->need;
                sum1(t);
                h->need = 0;
                cout << h->name << "的运行时间是" << h->turn << endl;
            }
            if(t->need>time) {
                clock += time;
                t->need -= time;
                sum2(t);
            }
            h = h->next;
            struct pcb *temp = h;
            while (count--) {
                if (temp->need == 0) {
                    num++;
                }
                temp = temp->next;
            }
            if (num == 4) break;
        }
        while (h->need == 0) {
            h = h->next;
        }
        while (h->need>time) {
            h->need -= time;
            h->turn += time;
        }
    //    return (h->turn + h->need);
        TIME = h->turn + h->need;
        cout<<h->name<<"的运行时间是 "<< h->turn + h->need << endl;
    //    cout << h->turn + h->need << endl;
    }
    int main() {
        cout << "请输入时间片大小:";
        cin >> time;
        cout << endl;
        cout << "请输入进程1和进程2的数量:";
        cin >> len1 >> len2;
        cout << endl;
        struct pcb *rq1, *rq2;
        cout << "请输入进程1的信息:" << endl;
        rq1 = create1();
        cout << "请输入进程2的信息:" << endl;
        rq2 = create2();
    /*    cout << "遍历进程1的信息:" << endl;
        see1(rq1);
        cout << "遍历进程2的信息:" << endl;
        see2(rq2);
        sort(rq2);
        cout << "排序后进程2的信息:" << endl;
        see2(rq2);*/
        cout << "队列rq1运行完毕,花费的时间为:" << endl;;
        fun1(rq1);
        cout << endl;
        cout << "队列rq2运行完毕,花费的时间为:" << endl;
        fun2(rq2);
        cout << endl;
        return 0;
    }

    运行结果:

    !!!!!!说一个令人自闭的事!!!!!!

    这个程序我调了好久,经常因为死循环的问题,输出不出来结果,真的快自闭了。。。

    从开始打断点慢慢调试的时候,找到卡住死循环的位置,慢慢改,终于改好了。

    还是要有耐心啊!!!

    不早啦,早点睡觉吧!晚安!

  • 相关阅读:
    金融资产的票面利率与实际利率
    对于确定承诺的外汇风险,既属于公允价值套期,又属于现金流量套期,怎么区分呢?
    套期工具(公允价值套期与现金流量套期)
    R语言使用 LOWESS技术图分析逻辑回归中的函数形式
    R语言ROC曲线下的面积
    R语言Poisson回归的拟合优度检验
    R语言在逻辑回归中求R square R方
    R平方/相关性取决于预测变量的方差
    stata具有异方差误差的区间回归
    R语言用于线性回归的稳健方差估计
  • 原文地址:https://www.cnblogs.com/laysfq/p/9859849.html
Copyright © 2020-2023  润新知