0


操作系统课程设计-时间片轮转法

一、课程设计题目及内容
设计一个按照时间片轮转法实现处理机调度的程序
时间片轮转法实现处理机调度的程序设计提示如下:
(1) 假设系统有n个进程,每个进程用一个进程控制块(PCB)来代表。进程控制块的格式如下表所示,且参数意义也相同。

进程名
链接指针
到达时间
估计运行时间
进程状态

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

int Num;//定义总进程数int Time =0;//定义系统时间int slice =1;//定义时间片长度#defineMAXSIZE20//定义就绪队列最大长度#definefalse0#definetrue1//定义PCB结构typedefstructPCB{char process;//定义进程名      int come_time;//定义到达时间int runtime;//定义运行时间char state;//定义进程状态(A:就绪,B:运行,C:完成)}PCB;//队列的顺序存储结构typedefstruct{
    PCB* base;//存储空间基地址int front;//头指针int rear;//尾指针}SqQueue;
PCB* pcb =new PCB[Num];//定义数组存放随机生成的进程

源代码:

#include<iostream>#include<ctime>usingnamespace std;int Num;//定义总进程数int Time =0;//定义系统时间int slice =1;//定义时间片长度#defineMAXSIZE20//定义就绪队列最大长度#definefalse0#definetrue1//定义PCB结构typedefstructPCB{char process;//定义进程名      int come_time;//定义到达时间int runtime;//定义运行时间char state;//定义进程状态(A:就绪,B:运行,C:完成)}PCB;//队列的顺序存储结构typedefstruct{
    PCB* base;//存储空间基地址int front;//头指针int rear;//尾指针}SqQueue;voidinit(PCB pcb[]);//初始化函数voidsort(PCB pcb[]);//根据到达时间对进程排序voidTime_slice(SqQueue& sq, PCB pcb[]);//时间片轮转法主函数voidshow(SqQueue& sq);//输出就绪队列voidinit(PCB pcb[]){
    PCB temp;for(int i =0; i < Num; i++)//随机生成进程信息{
        temp.process ='A'+ i;//进程名字从A开始
        temp.come_time =rand()%8;//到达时间1~8
        temp.runtime =rand()%9+1;//运行时间1~10
        temp.state ='A';//进程为就绪状态
        pcb[i]= temp;//初始化数组}}voidsort(PCB pcb[])//冒泡排序{for(int i =0; i < Num; i++){for(int j =0; j < Num -1- i; j++){if(pcb[j].come_time > pcb[j +1].come_time){
                PCB temp;
                temp = pcb[j];
                pcb[j]= pcb[j +1];
                pcb[j +1]= temp;}}}}voidTime_slice(SqQueue& sq, PCB pcb[]){int count =0;//计算完成运行的进程数int* record =newint[Num];//为标志数组分配空间for(int i =0; i < Num; i++){
        record[i]=false;//初始化标志数组}while(count != Num)//进程是否全部运行完毕{for(int i =0; i < Num; i++)//判断是否有新进程到达{if(Time >= pcb[i].come_time && record[i]==false)//系统时间大于等于进程到达时间{
                sq.base[sq.rear]= pcb[i];//进程进入就绪队列
                sq.rear =(sq.rear +1)% MAXSIZE;//队尾指针+1
                record[i]=true;//标志true}}if(sq.rear != sq.front)//当就绪队列不为空{if(sq.base[sq.front].runtime <= slice)//如果队头进程估计运行时间小于或等于时间片大小{printf("*************************系统时间:%d*************************\n\n", Time);printf("当前运行的是进程%c,该进程将运行完毕,系统时间过去%d\n", sq.base[sq.front].process, sq.base[sq.front].runtime);
                sq.base[sq.front].state ='C';//进程状态置为C
                Time += sq.base[sq.front].runtime;//系统时间经过该进程运行时间长度
                sq.base[sq.front].runtime =0;//进程运行完毕,估计运行时间为0show(sq);//输出就绪队列
                sq.front =(sq.front +1)% MAXSIZE;//进程出队
                count++;//完成运行的进程数+1}elseif(sq.base[sq.front].runtime > slice)//如果队头进程估计运行时间大于时间片大小{printf("*************************系统时间:%d*************************\n\n", Time);printf("当前运行的是进程%c,估计运行时间减%d,系统时间过去%d\n", sq.base[sq.front].process, slice, slice);
                sq.base[sq.front].state ='B';//进程状态置为B
                sq.base[sq.front].runtime -= slice;//估计运行时间减去一个时间片show(sq);//输出就绪队列   
                sq.base[sq.front].state ='A';//运行后进程状态置为B
                Time += slice;//系统时间经过一个时间片长度for(int i =0; i < Num; i++)//再次判断是否有新进程到达,新进程先插入队尾{if(Time >= pcb[i].come_time && record[i]==false)//系统时间等于进程到达时间{
                        sq.base[sq.rear]= pcb[i];//进程进入就绪队列
                        sq.rear =(sq.rear +1)% MAXSIZE;//队尾指针+1
                        record[i]=true;//标志true}}
                PCB e = sq.base[sq.front];//队头进程出队
                sq.front =(sq.front +1)% MAXSIZE;//队头指针+1
                sq.base[sq.rear]= e;//再插入队尾
                sq.rear =(sq.rear +1)% MAXSIZE;//队尾指针+1}}else//队列为空{printf("*************************系统时间:%d*************************\n", Time);printf("当前就绪队列为空!\n\n");
            Time++;//系统时间+1}}}voidshow(SqQueue& sq){printf("\n");int flag = sq.front;if(flag == sq.rear){printf("队列为空!");}while(flag != sq.rear)//遍历进程队列{printf("进程名:%c\t到达时间:%d\t运行时间:%d\t 进程状态:%c\n",
            sq.base[flag].process, sq.base[flag].come_time, sq.base[flag].runtime, sq.base[flag].state);
        flag =(flag +1)% MAXSIZE;}printf("\n");}intmain(){
    SqQueue sq;srand(unsignedint(time(NULL)));
    Num =rand()%3+4;//随机生成进程个数
    PCB* pcb =new PCB[Num];//定义数组存放随机生成的进程
    sq.base =new PCB[MAXSIZE];//为队列分配数组空间if(!sq.base)//初始化队列exit(1);
    sq.front = sq.rear =0;printf("进程个数为%d个,时间片大小为%d,进程状态(A:就绪,B:运行,C:完成)\n", Num, slice);init(pcb);//初始化进程信息printf("以下为初始化的进程信息:\n");for(int i =0; i < Num; i++)//打印初始化的进程信息{printf("进程名:%c\t到达时间:%d\t运行时间:%d\t进程状态:%c\n",
            pcb[i].process, pcb[i].come_time, pcb[i].runtime, pcb[i].state);}printf("\n");sort(pcb);//根据到达时间对进程排序printf("以下为排序后的进程信息:\n");for(int i =0; i < Num; i++)//打印排序后的进程{printf("进程名:%c\t到达时间:%d\t运行时间:%d\t进程状态:%c\n",
            pcb[i].process, pcb[i].come_time, pcb[i].runtime, pcb[i].state);}printf("\n");Time_slice(sq, pcb);//时间片轮转法}

实验结果截图比较多,就不放上来了,可以直接复制代码到vs上运行即可看到结果

标签:

本文转载自: https://blog.csdn.net/weixin_47178179/article/details/119203506
版权归原作者 @打工人 所有, 如有侵权,请联系我们删除。

“操作系统课程设计-时间片轮转法”的评论:

还没有评论