基于动态优先级的时间片轮转调度算法c语言

  1. 动态优先级的时间片轮转调度算法

    在多道程序运行环境下,进程数目一般多于处理机数目,使得进程要通过竞争来使用处理机。这就要求系统能按某种算法,动态地把处理机分配给就绪队列中的一个进程,使之运行,分配处理机的任务是由进程调度程序完成的。一个进程被创建后,系统为了便于对进程进行管理,将系统中的所有进程按其状态,将其组织成不同的进程队列。于是系统有运行进程队列、就绪进程队列和各种事件的进程等待队列。进程调度的功能就是从就绪队列中挑选一个进程到处理机上运行。进程调度的算法有多种,常用的有优先级调度算法、先来先服务算法、时间片轮转算法。

    进程是程序在处理机上的执行过程。进程存在的标识是进程控制块(PCB),进程控制块参考结构如下:

    typeedef struct node

    {

       char  name[10];    /*进程标识符*/

       int  prio;          /*进程优先数*/

       int  round;        /*进程时间片轮转时间片*/

       int  cputime       /*进程占用CPU时间*/

       int  neentime      /*进程到完成还需要的时间*/

       int  count;        /*计数器*/

       char  state;       /*进程的状态*/

       struct node   *next;   /*链指针*/

    }PCB;

    系统创建一个进程,就是由系统为某个程序设置一个PCB,用于对该进程进行控制和管理。进程任务完成,由系统收回其PCB,该进程便消亡。每个进程可以有三个状态:运行态、就绪态和完成状态。

    1. 使用优先数调度算法完成进程的调度
      1. 采用动态优先数法确定进程的优先级别。
      2. 设计三个链队列,分别用来表示运行队列、就绪队列和完成队列。
      3. 用户输入进程标识符以及进程所需要的时间,申请空间存放进程PCB信息。

    优先数调度算法为每个进程设一个优先数,它总是把处理机给就绪队列中具有最高优先权的进程。常用的算法有静态优先数法和动态优先数法。

    动态优先数法使进程的优先权随时间而改变。初始的进程优先数取决于进程运行所需要的时间,时间长则优先数低。可采取将进程优先数定为一个较大的数(比如50)减去进程运行所需要的时间。

    随着进程的运行对优先数进行调整,每次运行时都是从就绪队列中选取优先数最大的进程运行。以一个时间片为固定周期T,每个周期动态调整各个进程的优先级,执行进程优先级降低(优先数减小),就绪进程优先级提升(优先数增加),每个时间片开始时,重新选择当前优先级最高的进程投入运行。如果进程所需时间为0,说明进程运行完毕,将其状态变为完成状态“F”,将此进程PCB插入到完成队列中,重复上述过程,直到就绪队列为空,所有进程都变为完成状态为止。

    2.使用时间片轮转算法完成进程的调度

    时间片轮转调度:具体做法是调度程序每次把CPU分配给当前最高优先级进程使用一个时间片。当这个时间片结束时,强迫该进程让出处理器,进行下一轮优先级调度,直至就绪队列中所有进程都运行完成为止。实现这种调度要使用一个间隔时钟。当一个进程开始运行时,就将时间片的值置入间隔时钟内,当发生间隔时钟中断时,就表明该进程连续运行的时间已超过一个规定的时间片。此时,中断处理程序就通知处理器调度进行处理器的切换工作。

  2. 流程图
  3. 代码段
    #include <stdio.h>
    #include <stdlib.h>
    #define CHOICE 50 /*用来初始化进程的优先级*/
    
    typedef struct node
    {
        char name[10];     /*进程标识符*/
        int prio;          /*进程优先数*/
        int round;         /*进程时间片轮转时间片*/
        int cputime;       /*进程占用CPU时间*/
        int needtime;      /*进程到完成还需要的时间*/
        int count;         /*计数器*/
        char state;        /*进程的状态*/
        struct node *next; /*链指针*/
    } PCB, *Process;
    
    /*初始化PCB*/
    Process initPCB(int time)
    {
        Process process = (Process)malloc(sizeof(PCB));
        printf("请输入进程的标识符和运行所需时间\n");
        scanf("%s %d", process->name, &(process->needtime));
        process->cputime = 0;
        process->round = time;
        process->prio = CHOICE - process->needtime;
        process->state = 'R';
        process->count = 0;
        process->next = NULL;
        return process;
    }
    // 初始化进程队列
    Process initProcessQueue()
    {
        Process process = (Process)malloc(sizeof(PCB));
        process->next = NULL;
        return process;
    }
    /*入队操作,按照优先级的大小来入队,类似于插入排序*/
    void insertProcess(Process p, Process ready1)
    {
        Process ready = ready1;
    
        //如果就绪队列为空直接插入
        if (!(ready->next))
        {
            ready->next = p;
        }
        else
        {
            //遍历链表,并插入,temp用来记录是否插入队尾
            int temp = 0;
            while (ready->next)
            {
    
                if (p->prio > ready->next->prio)
                {
                    p->next = ready->next;
                    ready->next = p;
                    temp = 1;
                    break;
                }
                else
                {
                    ready = ready->next;
                }
            }
            //比所有的优先级都小,插入队尾
            if (!temp)
            {
                ready->next = p;
            }
        }
    }
    
    /*出队操作,从首元结点开始出队*/
    Process deleteProcess(Process p)
    {
        if (!p->next)
        {
            return p;
        }
        Process q = p->next;
        p->next = q->next;
        q->next = NULL;
        return q;
    }
    
    /*动态优先级增加,对队列中所有优先级动态增加*/
    void addPriority(Process p, int priority)
    {
        Process q = p;
        while (q->next)
        {
            q->next->prio += priority;
            q = q->next;
        }
    }
    /*打印函数*/
    void Output(Process p)
    {
    
        printf("%-10s", p->name);
        printf("%-10d", p->round);
        printf("%-10d", p->cputime);
        printf("%-10d", p->needtime);
        printf("%-10d", p->prio);
        printf("%-10c", p->state);
        printf("%-10d", p->count);
        printf("\n");
    }
    /*打印函数*/
    void Print(Process p)
    {
        if (!p->next)
        {
            printf("队列为空\n");
            return;
        }
        printf("进程号   时间片   cpu时间  所需时间   优先数    状态    执行次数\n");
        while (p->next)
        {
            Output(p->next);
            p = p->next;
        }
    }
    
    void runProcess(Process process)
    {
        /*运行进程,相应的参数改变*/
        process->state = 'r';
        process->needtime -= process->round;
        process->cputime += process->round;
        process->prio -= 5; //运行的进程优先级减5
        process->count += 1;
    }
    
    int main()
    {
        int round; //时间片
        printf("请输入时间片的大小\n");
        scanf("%d", &round);
        /*创建就绪,运行,完成,3个队列*/
        Process run = initProcessQueue();
        Process ready = initProcessQueue();
        Process finish = initProcessQueue();
        /*创建进程,并初始化,加入就绪队列*/
        printf("请输入你要创建的进程数量\n");
        int count; //进程数
        scanf("%d", &count);
        for (int i = 0; i < count; i++)
        {
            Process process = initPCB(round);
            insertProcess(process, ready);
        }
        /*运行状态,直到就绪队列为空,才停止*/
        while (ready->next)
        {
            if (!run->next)
            {
                Process q = deleteProcess(ready); //就绪队列出队
                insertProcess(q, run);            //加入运行队列
                runProcess(q);
                addPriority(ready, 2);  //就绪队列中优先级加2
                q = deleteProcess(run); //从运行队列出队
                if (q->needtime <= 0)   //判断运行时间是否小于0
                {
    
                    q->cputime += q->needtime;
                    q->needtime = 0;
                    q->state = 'F';
                    insertProcess(q, finish); //小于等于加入完成队列,并改变相应的参数
                }
                else
                {
                    q->state = 'R';
                    insertProcess(q, ready); //大于继续加入就绪队列
                }
            }
            //每执行一次打印每个队列,观察执行情况
            printf("************************************************************************");
            printf("\n");
            printf("完成队列:\n");
            Print(finish);
            printf("\n");
            printf("就绪队列:\n");
            Print(ready);
            printf("\n");
            printf("运行队列:\n");
            Print(run);
            printf("\n");
        }
    
        return 0;
    }
    /* Thans for Min! */

  4. 运行截图

  5. 注意至于代码中的优先级变换,可以自定义,优先级的变化,我的是执行优先级就要减5,没执行的都加2,其实就是相对差值的变换,根据自己的需要来调整,不是固定的,还有,这个实验的模拟的进程到达时间都是0,如果相应加一个到达时间,在PCB里添加一个相应的信息即可,在定义一个记录时间的全局变量,在判断一下,运用了数据结构中链表的知识,掌握一下链表的增加和删除就可写出这个模拟实验了,本次实验采用的c的代码,在cpp上可能会不兼容,以上代码均在vscode上跑过。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值