进程的调度队列----时间片轮转法及优先数算法

一、 实验目的
在采用多道程序设计的系统中,有若干个进程同时处于就绪状态。当就绪进程个数大于处理机数时,就必须依照某种调度策略决定哪些进程可以分到处理机,本实验模拟在单处理机情况下的处理机调度。
二、实验内容
1、 设计一个进程控制块PCB
包括:进程名、进程优先数、进程所占CPU时间、还需要CPU时间、进程状态、下一列指针

2、建立进程就绪队列:要求按照不同调度算法建立就绪队列

3、 编制两个调度算法,进程数由用户从键盘输入 (1)时间片轮转法(时间片为2) (2)优先数算法
初始优先数 = 50 - 运行时间
每运行一次优先数减3,时间片为2。

4、运行结果 (提示:name为进程名; cputime 为CPU已运行的时间单位数; needtime 为进程还需要运行的时间单位数;
count为已经运行的轮数;round为被分配的时间片数量; state中R代表运行,W代表等待。)

一、 时间片轮转法(带下划线表示输入)

输入:
input name and needtime:
a1 3
a2 2
a3 4
a4 2
a5 1

显示结果:
Name cputime needtime count round state
a1 0 3 0 2 R
a2 0 2 0 2 W
a3 0 4 0 2 W
a4 0 2 0 2 W
a5 0 1 0 2 W
就绪队列:a2、a3、a4、a5
完成队列:

Name cputime needtime count round state
a2 0 2 0 2 R
a3 0 4 0 2 W
a4 0 2 0 2 W
a5 0 1 0 2 W
a1 2 1 1 2 W
就绪队列:a3、a4、a5 、a1
完成队列:

Name cputime needtime count round state
a3 0 3 0 2 R
a4 0 2 0 2 W
a5 0 4 0 2 W
a1 2 1 1 2 W
a2 2 0 1 2 F
就绪队列:a4、a5 、a1
完成队列:a2

Name cputime needtime count round state
a1 3 0 2 2 F
a2 2 0 1 2 F
a3 4 0 2 2 F
a4 2 0 1 2 F
a5 1 0 1 2 F
就绪队列:
完成队列:a2、a4、a5、a1、a3

二、优先数算法(带下划线表示输入)

输入:
input name and needtime:
a1 3
a2 2
a3 4
a4 2
a5 1
显示结果:

Name cputime needtime count pri state
a5 0 1 0 49 R
a2 0 2 0 48 W
a4 0 2 0 48 W
a1 0 3 0 47 W
a3 0 4 0 46 W
就绪队列:a2、a4、a1、a3
完成队列:

Name cputime needtime count pri state
a2 0 2 0 48 R
a4 0 2 0 48 W
a1 0 3 0 47 W
a3 0 4 0 46 W
a5 1 0 1 49 F
就绪队列:a4、a1、a3
完成队列:a5

Name cputime needtime count pri state
a4 0 2 0 48 R
a1 0 3 0 47 W
a3 0 4 0 46 W
a2 2 0 1 48 F
a5 1 0 1 49 F
就绪队列:a1、a3
完成队列:a5、a2

Name cputime needtime count pri state
a1 0 3 0 47 R
a3 0 4 0 46 W
a4 2 0 1 48 F
a2 2 0 1 48 F
a5 1 0 1 49 F
就绪队列:a3、a2 、a4
完成队列:a5、a2、a4

Name cputime needtime count pri state
a5 1 0 1 49 F
a2 2 0 1 48 F
a4 2 0 1 48 F
a1 3 0 2 44 F
a3 4 0 2 43 F
就绪队列:
完成队列:a5、a2、a4、a1、a3

一、时间片轮转法

代码演示:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<malloc.h>
#include<string.h>

#define N 10  //定义最大进程数
#define round 2//定义时间片大小
int num = 1;//记录进程执行次数

//定义队列结点数据类型
typedef struct pcb {

    char Name[10];//进程标识数
    int cuptime;//进程已经占用的cpu时间
    int needtime;//进程还需要的时间
    int count;//进程已经转的轮数
    char state;//进程运行状态:R or W
    struct pcb* next;

}pcb, * PCB;

//定义队列数据类型
typedef struct queue
{
    int count;//当前队列的进程总数
    PCB head, tail;//队头
}QUEUE, * PQUEUE;

//初始化队列结点
PCB creatQueueNode(int i)
{
    PCB newNode = (PCB)malloc(sizeof(pcb));
    printf("输入进程%d的标示符:", i);
    scanf("%s", newNode->Name);
    getchar();
    printf("输入进程%d还需要的cpu时间:", i);
    scanf("%d", &newNode->needtime);
    getchar();
    newNode->count = 0;
    newNode->cuptime = 0;
    newNode->state = 'W';
    newNode->next = NULL;
    return newNode;
}

//入队
void QueueEn(PQUEUE queue, PCB newNode)
{
    if (queue == NULL)
    {
        return;
    }
    if (queue->count == 0)
    {
        queue->head = queue->tail = newNode;
    }
    else
    {
        queue->tail->next = newNode;
        queue->tail = newNode;
    }
    queue->count++;
    return;
}

//出队
void QueueOut(PQUEUE queue)
{
    if (queue == NULL || queue->count == 0)
    {
        return;
    }
    PCB temp = queue->head->next;
    free(queue->head);
    queue->head = temp;
    queue->count--;
    return;
}

//创建进程队列
PQUEUE InitQueueProcess(int n)
{
    PQUEUE queue = (PQUEUE)malloc(sizeof(QUEUE));
    queue->head = queue->tail = NULL;
    queue->count = 0;

    int i = 0;
    for (i = 1; i <= n; i++)
    {
        PCB newNode = creatQueueNode(i);//创建并初始化队列结点
        QueueEn(queue, newNode);//入队
    }
    return queue;
}

//展示当前进程结果
void showQueue(PQUEUE queue, PQUEUE queue_1)
{
    printf("\n\n**************第%d次执行进程状态********************\n", num);
    printf("Name  cpuround  needtime  count  round  state\n");
    PCB pMove = queue->head;
    while (pMove)
    {
        printf("%s\t%d\t%d\t  %d\t  %d\t%c\n",///
            pMove->Name, pMove->cuptime, pMove->needtime, pMove->count, 2, pMove->state);
        pMove = pMove->next;
    }
    pMove = queue_1->head;
    while (pMove)
    {
        printf("%s\t%d\t%d\t  %d\t  %d\t%c\n",
            pMove->Name, pMove->cuptime, pMove->needtime, pMove->count, 2, pMove->state);
        pMove = pMove->next;
    }

    //输出就绪队列
    printf("就绪队列:");
    pMove = queue->head;
    while (pMove)
    {
        if (pMove->state == 'W')
            printf("%s、", pMove->Name);
        pMove = pMove->next;
    }
    printf("\n");

    //输出完成队列
    printf("完成队列:");
    pMove = queue_1->head;
    while (pMove)
    {
        printf("%s、", pMove->Name);
        pMove = pMove->next;
    }

    printf("\n\n**************************************************\n");
    return;
}

//每执行一次进程就输出一次就绪队列的结果
void RunProcess(PQUEUE queue, PQUEUE queue_1)
{
    if (queue == NULL || queue->count == 0)
        return;

    //当进程未全部执行完毕时,一直执行
    while (queue->head != NULL)
    {
        //执行一次队头进程
        PCB pMove = queue->head;
        pMove->state = 'R';
        //显示当前队列状态
        showQueue(queue, queue_1);
        if (pMove->needtime > 0)
        {
            pMove->cuptime += round;
            pMove->needtime -= round;
            //计算是否完成
            if (pMove->needtime <= 0)
            {
                pMove->needtime = 0;
            }
        }
        //深拷贝队头结点
        PCB temp = (PCB)malloc(sizeof(pcb));
        temp->count = pMove->count;
        temp->cuptime = pMove->cuptime;
        strcpy(temp->Name, pMove->Name);
        temp->needtime = pMove->needtime;
        temp->state = pMove->state;
        temp->next = NULL;
        if (temp->needtime == 0)
        {
            //temp入完成队列
            temp->state = 'F';
            QueueEn(queue_1, temp);
            if (queue->count == 1)
            {
                num++;
                QueueOut(queue);
                showQueue(queue, queue_1);
                return;
            }
        }
        else
        {
            //temp入就绪队列
            temp->state = 'W';
            QueueEn(queue, temp);
        }
        temp->count++;//执行次数加一
        //队头出队
        QueueOut(queue);

        num++;
    }
    return;
}


int main() {

    //创建就绪队列进程
    printf("输入你要创建的进程数:");
    int n;
    scanf("%d", &n);
    getchar();
    PQUEUE readyQueue = InitQueueProcess(n);
    PQUEUE compeletQueue = InitQueueProcess(0);

    printf("\n\n");

    //执行队列进程
    RunProcess(readyQueue, compeletQueue);//简单轮转法Round Robin

    return;
}

输入:
在这里插入图片描述

输出:

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

二、优先数算法:

代码演示:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define round 2//定义时间片大小
int num = 1;//记录进程执行次数

//定义队列结点数据类型
typedef struct pcb {

    char Name[10];//进程名称
    int cuptime;//进程已经占用的cpu时间
    int needtime;//进程还需要的时间
    int count;//进程已经转的轮数
    int pri;//进程的优先数
    char state;//进程运行状态:R or W or F
    struct pcb* next;

}pcb, * PCB;

//定义队列数据类型
typedef struct queue
{
    int count;//当前队列的进程总数
    PCB head, tail;//队头
}QUEUE, * PQUEUE;

//初始化队列结点
PCB creatQueueNode(int i)
{
    PCB newNode = (PCB)malloc(sizeof(pcb));
    printf("输入进程%d的标示符:", i);
    scanf("%s", newNode->Name);
    getchar();
    printf("输入进程%d还需要的cpu时间:", i);
    scanf("%d", &newNode->needtime);
    getchar();

    newNode->pri = 50 - newNode->needtime;//初始化优先数
    newNode->count = 0;
    newNode->cuptime = 0;
    newNode->state = 'W';
    newNode->next = NULL;
    return newNode;
}

//入队
void QueueEn(PQUEUE queue, PCB newNode)
{
    if (queue == NULL)
    {
        return;
    }
    if (queue->count == 0)
    {
        queue->head = queue->tail = newNode;
    }
    else
    {
        queue->tail->next = newNode;
        queue->tail = newNode;
    }
    queue->count++;
    return;
}

//出队
void QueueOut(PQUEUE queue)
{
    if (queue == NULL || queue->count == 0)
    {
        return;
    }
    PCB temp = queue->head->next;
    free(queue->head);
    queue->head = temp;
    queue->count--;
    return;
}

//创建进程队列
PQUEUE InitQueueProcess(int n)
{
    PQUEUE queue = (PQUEUE)malloc(sizeof(QUEUE));
    queue->head = queue->tail = NULL;
    queue->count = 0;

    int i = 0;
    for (i = 1; i <= n; i++)
    {
        PCB newNode = creatQueueNode(i);//创建并初始化队列结点
        QueueEn(queue, newNode);//入队
    }
    return queue;
}


//排序,仅交换队列结点的值
void sortQueue(PQUEUE queue)
{

    int i = 0, j = 0;
    int n;
    for (i = 0; i < queue->count - 1; i++)
    {
        for (j = 0; j < queue->count - 1 - i; j++)
        {
            PCB pMove = queue->head;
            n = 0;
            while (n < j)
            {
                pMove = pMove->next;
                n++;
            }
            PCB pMoveNext = pMove->next;

            if (pMove->pri < pMoveNext->pri)
            {
                int t_count = pMove->count;
                int t_cuptime = pMove->cuptime;
                char t_Name[10];
                strcpy(t_Name, pMove->Name);
                int t_needtime = pMove->needtime;
                int t_pri = pMove->pri;
                char t_state = pMove->state;

                pMove->count = pMoveNext->count;
                pMove->cuptime = pMoveNext->cuptime;
                strcpy(pMove->Name, pMoveNext->Name);
                pMove->needtime = pMoveNext->needtime;
                pMove->pri = pMoveNext->pri;
                pMove->state = pMoveNext->state;

                pMoveNext->count = t_count;
                pMoveNext->cuptime = t_cuptime;
                pMoveNext->needtime = t_needtime;
                strcpy(pMoveNext->Name, t_Name);
                pMoveNext->pri = t_pri;
                pMoveNext->state = t_state;
            }
        }
    }

    return;
}



//展示当前进程结果
void showQueue(PQUEUE queue, PQUEUE queue_1)
{
    printf("\n\n**************第%d次执行进程状态********************\n", num);
    printf("Name  cpuround  needtime  count  pri  state\n");
    PCB pMove = queue->head;
    while (pMove)
    {
        printf("%s\t%d\t%d\t  %d\t  %d\t%c\n",///
            pMove->Name, pMove->cuptime, pMove->needtime, pMove->count, pMove->pri, pMove->state);
        pMove = pMove->next;
    }
    pMove = queue_1->head;
    while (pMove)
    {
        printf("%s\t%d\t%d\t  %d\t  %d\t%c\n",
            pMove->Name, pMove->cuptime, pMove->needtime, pMove->count, pMove->pri, pMove->state);
        pMove = pMove->next;
    }

    //输出就绪队列
    printf("就绪队列:");
    pMove = queue->head;
    while (pMove)
    {
        if (pMove->state == 'W')
            printf("%s、", pMove->Name);
        pMove = pMove->next;
    }
    printf("\n");

    //输出完成队列
    printf("完成队列:");
    pMove = queue_1->head;
    while (pMove)
    {
        printf("%s、", pMove->Name);
        pMove = pMove->next;
    }

    printf("\n\n**************************************************\n");
    return;
}


//优先数算法
void RunProcess(PQUEUE queue, PQUEUE queue_1)
{
    if (queue == NULL || queue->count == 0)
        return;

    //当进程未全部执行完毕时,一直执行
    while (queue->head != NULL)
    {
        //对进程优先数进行排序
        sortQueue(queue);

        //执行一次队头进程
        PCB pMove = queue->head;
        pMove->state = 'R';
        //显示当前队列状态
        showQueue(queue, queue_1);
        if (pMove->needtime > 0)
        {
            pMove->cuptime += round;
            pMove->needtime -= round;
            
            //计算是否完成
            if (pMove->needtime <= 0)
            {
                pMove->needtime = 0;
            }
        }
        //深拷贝队头结点
        PCB temp = (PCB)malloc(sizeof(pcb));
        temp->count = pMove->count;
        temp->cuptime = pMove->cuptime;
        strcpy(temp->Name, pMove->Name);
        temp->needtime = pMove->needtime;
        temp->pri = pMove->pri;
        temp->state = pMove->state;
        temp->next = NULL;
        if (temp->needtime == 0)
        {
            //temp入完成队列
            temp->state = 'F';
            QueueEn(queue_1, temp);
            if (queue->count == 1)
            {
                num++;
                QueueOut(queue);
                showQueue(queue, queue_1);
                return;
            }
        }
        else
        {
            //temp入就绪队列
            temp->pri -= 3;//优先数-3
            temp->state = 'W';
            QueueEn(queue, temp);
        }
        temp->count++;//执行次数加一
        //队头出队
        QueueOut(queue);

        num++;
    }
    return;
}



int main(int argc, char* argv[])
{
	
    //创建就绪队列进程
    printf("输入你要创建的进程数:");
    int n;
    scanf("%d", &n);
    getchar();
    PQUEUE readyQueue = InitQueueProcess(n);
    PQUEUE compeletQueue = InitQueueProcess(0);

    printf("\n\n");

    //执行队列进程
    RunProcess(readyQueue, compeletQueue);//简单轮转法Round Robin


	return 0;
}

输入:
在这里插入图片描述

输出:
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

如果有啥问题可以留言交流,我一定及时回复;

  • 4
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值