广州大学课程设计–时间片轮转法(RR)实现处理机调度程序 :)

广州大学课程设计–时间片轮转法

操作系统课程设计

要求:书写课程设计报告,报告中应该包含如下内容:
(1)课程设计题目及内容
(2)程序中使用的数据结构及主要符号说明
(3)程序流程图和带有注释的源程序
(4)执行程序名,并打印程序运行时的初值和运算结果
(5)实验结果分析,实验收获和体会
(6)实验的改进意见和建议。

以下六个题目任选一题

题目一:设计一个按照时间片轮转法实现处理机调度的程序 时间片轮转法实现处理机调度的程序设计提示如下:
(1)假设系统有n个进程,每个进程用一个进程控制块(PCB)来代表。进程控制块的格式如下表所示,且参数意义也相同。
进程名 链接指针 到达时间 估计运行时间 进程状态

(2)按照进程到达的先后顺序排成一个循环队列,设一个队首指针指向第一个到达进程的首址。另外再设一个当前运行进程指针,指向当前正运行的进程。
(3)执行处理机调度时,首先选择队首的第一个进程运行。
(4)由于本题目是模拟实验,所以对被选中的进程并不实际启动运行,而只是执行如下操作:
1)估计运行时间减1;
2)输出当前运行进程的名字。
用这两个操作来模拟进程的一次运行。
(5)进程运行一次后,以后的调度则将当前指针依次下移一个位置,指向下一个进程,即调整当前运行指针指向该进程的链接指针所指进程,以指示应运行进程,同时还应判断该进程的剩余运行时间是否为0,若不为0,则等待下一轮的运行,若该进程的剩余运行时间为0,则将该进程的状态置为完成状态“C”,并退出循环队列。
(6)若就绪队列不为空,则重复上述的步骤(4)和(5)直到所有进程都运行完为止。
(7)在所设计的调度程序中,应包含显示或打印语句,以便显示或打印每次选中进程的名称及运行一次后队列的变化情况。

思路

  • [Ⅰ] 先建立链式循环队列,然后按照到达时间从小到大排序
  • [Ⅱ] 将排好序的队列输入到RR算法
  • [Ⅲ] 将未结束的进程的运行时间轮流减一,若有的进程结束了则标记,直至所有进程运行时间为0。

一、程序流程图
在这里插入图片描述
二、源代码

// 课设_时间片轮转法_处理机调度.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include<stdio.h>
#include<stdlib.h>
#include<ctime>
using namespace std;
#define Length 10
int n;
int Round = 0;//轮转数
struct PCB//一个头指针,无数据,下一个为头,rear一直指向尾
{
    char Name[Length];
    PCB* next;
    int ArriveTime;//到达时间
    int RunTime;//运行时间
    char state;//状态(A为未完成态,C为完成态)
}*head;//头
void Creat(PCB* c)
{
    srand((unsigned)time(NULL));
    PCB* l, * s;
    c = (PCB*)malloc(sizeof(PCB));
    c->next = NULL;
    l = c;//头节点
    printf("请输入总进程数:");
    scanf_s("%d", &n);
    printf("随机生成\t序号\t初始化进程(进程名'\'到达时间'\'估计运行时间)\n");
    for (int i = 0; i < n; ++i)
    {
        s= (PCB*)malloc(sizeof(PCB));
        s->next = NULL;
        /*printf("%d\t", i);
        scanf_s("%s", &s->Name,sizeof(s->Name));
        scanf_s("%d", &s->ArriveTime);
        scanf_s("%d", &s->RunTime);*/
        s->Name[0] = char(i + 65);
        for (int j = 1; j < Length; ++j)
        {
            s->Name[j] = NULL;
        }
        s->ArriveTime = rand() % 10;
        s->RunTime = rand()%10+1;
        s->state = 'A';//未运行   
        l->next = s;
        if (i == 0)
            head = s;
        l = l->next;
    }
    //rear = l;
    l->next = head;
    printf("\n");
}
void Output(PCB* c)
{  
    if (n == 0)
    {
        exit(1);
    }
    PCB* l;
    l = c;
    printf("名字\t到达时间\t估计运行时间\t状态\n");
    do
    {
        if (l->state != 'C')//该进程未结束
        {
            printf("%s\t", l->Name);
            printf("%d\t\t", l->ArriveTime);
            printf("%d\t\t", l->RunTime);
            //cout<<l->state<<endl;
            printf("%c\n", l->state);
            l = l->next;
        }
        else
            l = l->next;
    } while (l != head);
    printf("\n");
}
void Output2(PCB* c,int time)//输出运行队列
{
    PCB* l;
    l = c;
    printf("名字\t到达时间\t估计运行时间\t状态\n");
    do
    {
        if (l->state != 'C'&&l->ArriveTime<=time)//该进程未结束
        {
            printf("%s\t", l->Name);
            printf("%d\t\t", l->ArriveTime);
            printf("%d\t\t", l->RunTime);
            //cout<<l->state<<endl;
            if (l->RunTime == 0)
            {
                printf("C\n");
            }
            else
            {
                printf("%c\n", l->state);
            }
            l = l->next;
        }
        else
            l = l->next;
    } while (l != head);
    printf("\n");
}
void SortPCB(PCB* c)
{
    PCB* l,*tmp,*s;
    tmp=(PCB*)malloc(sizeof(PCB));
    l = c;
    printf("--------------------------根据到达时间排序--------------------------\n");
    for(int i=0;i<n;++i)
    {
        s = l->next;
        for(int j=0;j<n-1;++j)
        {
            if (s->ArriveTime > l->ArriveTime)//冒泡
            {        
                for (int i = 0; i < Length; ++i)
                {
                    tmp->Name[i] = l->Name[i];
                }               
                tmp->ArriveTime = l->ArriveTime;
                tmp->RunTime = l->RunTime;
                tmp->state = l->state;
                for (int i = 0; i < Length; ++i)
                {
                    l ->Name[i] = s->Name[i];
                }
                l->ArriveTime = s->ArriveTime;
                l->RunTime = s->RunTime;
                l->state = s->state;
                for (int i = 0; i < Length; ++i)
                {
                    s->Name[i] = tmp->Name[i];
                }
                s->ArriveTime = tmp->ArriveTime;
                s->RunTime = tmp->RunTime;
                s->state = tmp->state;
            }
            s = s->next;
        } 
        l = l->next;
    } 

}
void RR(PCB *c)//时间片轮转法
{
    printf("--------------------------时间片轮转法--------------------------\n");
    int m = n;//剩余进程数
    PCB* l;
    l = c;
    while (l->RunTime > 0)
    {
        printf("Round:\t%d",Round);    
        //把就绪队列里面到达时间的PCB加入运行队列
        if (l->ArriveTime <= Round)
        {
            printf("--正在运行%s", l->Name);
            printf("进程\n");
            l->RunTime--;

            Output2(c,Round);
            if (l->RunTime == 0)//结束了
            {
                l->state = 'C';
                m--;
                printf("进程%s已经结束,被删除\n", l->Name);

            }
            /*else
            {
                printf("--当前没有进程运行\n");
            }*/
            int count = 0;
            while (l->next->ArriveTime > Round&&count!=m)//跳过未到到达时间的进程且还有到了到达时间的队列
            {
                l = l->next;
                count++;
            }
            /* 测试样例        
            1 3 2
            2 3 1
            3 0 1
            4 0 5
            5 10 2
            */
            l = l->next;
        }
        else
        {
            printf("--当前无进程运行\n");
        }
        Round++;
        while (m && l->RunTime == 0)
        {
            l = l->next;//跳过已经结束的进程
        }
    }
    printf("--------------------------END--------------------------\n");
}
int main()
{
    printf("-----------------------------LSZNB-----------------------------\n");
    PCB*c = (PCB*)malloc(sizeof(PCB));
    Creat(c);
    Output(head);
    SortPCB(head);
    Output(head);
    RR(head);
}

三、运行结果
举个简单的例子
A 0 2
B 0 2
C 2 3
那么顺序应该是A->B->A(A退出)->B(退出)->C->C->C(退出)
这里就展示一个简单(随机生成的,不是上面那个)的例子,数量太多不好截屏
在这里插入图片描述
在这里插入图片描述
四、实验结果分析

  1. 因为算法比较简单,值得注意的地方就是要考虑数据结构(PCB)的初始化。
  2. 能进一步了解到进程的运作模式。
  3. 这类题目的难度较低,答辩可能会轻松些但是得分的上限不会很高。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章