实验三:时间片轮转法完成进程调度
一、实验目的:
(1)加深对进程的理解
(2)理解进程控制块的结构
(3)理解进程运行的并发性
(4)掌握时间片轮转法进程调度算法
实验内容:
(1)建立进程控制块
(2)设计三个链队列,分别表示运行队列、就绪队列和完成队列
(3)用户输入进程标识符以及进程所需的时间,申请空间存放进程PCB言息。
(4)每一个时间片结束输出各进程的进程号,CPU时间(即已经占用的CPU时间),所需时间(即还需要的CPU时间),以及状态(即用W表示等待,R表示运行,F表示完成)
实验程序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct node
{
char name[10];/* 进程标识符*/ int prio;/* 进程优先数*/
int round;/* 进程时间轮转时间片*/
int cputime; /*进程占用CPU时间*/
int needtime; /* 进程到完成还要的时间*/
int count;/* 计数器*/
char state; /* 进程的状态*/
struct node *next; /* 链指针*/
}PCB;
PCB *finish,*ready,*tail,*run; // 队列指针
int N,t; // 进程数,时间片的大小
void firstin()
{
run二ready;//就绪队列头指针赋值给运行头指针
run->state='R'; //进程状态变为运行态
ready=ready->next; //就绪队列头指针后移到下一进程
}
void prt1(char a)// 输出标题函数
{
if(toupper(a)=='P')// 优先级法
\n");} printf("进程名占用CPU时间到完成还要的时间轮转时间片状态
void prt2(char a,PCB *q)〃进程PCB输出
if(toupper(a)=='P')// 优先级法的输出
printf("%4s %8d %12d %14d %8c\n",q->name,q->cputime,q->needtime,q->roun d,q->state);
}
void prt(char algo)// 输出函数二、
{
PCB *p;
prt1(algo);// 输出标题
if(run!=NULL)// 如果运行指针不空prt2(algo,run);// 输出当前正在运行的PCB p=ready;// 输出就绪队列PCB while(p!=NULL)
{
prt2(algo,p);
p=p->next;
}
p=finish;// 输出完成队列的PCB while(p!=NULL)
{
prt2(algo,p);
p=p->next;
}
getchar(); // 按住任意键继续
}
void insert(PCB *q)// 时间片轮转的插入算法
{
PCB *p1,*s,*r;
s=q;〃待插入的PCB指针
p仁ready;//就绪队列头指针
r=p1;//*r做pl的前驱指针
while(p1!=NULL)
if(p1->round<=s->round)
{
r=p1;
p1=p1->next;
}
if(r!=p1)
{
r->next=s;
s->next=p1;
else
{
s->next=p1;// 否则插入在就绪队列的头
ready=s;
}
}
void create(char alg)// 时间片轮转法创建链表进程PCB {
PCB *p;
int i,time;
char na[10];
ready=NULL;
finish=NULL;
run=NULL;
printf(" 输入进程名及其需要运行的时间(中间以空格隔开):\n");
for(i=1;i<=N;i++)
{
p=new PCB;
scanf("%s %d",&na,&time); strcpy(p->name,na);
p->cputime=0;
p->needtime=time;
p->state='W';// 进程的状态
p->round=0;
if(ready!=NULL)
insert(p);
else
{ p->next=ready; ready=p;
}
}
printf("************* 时间片轮转法进程调度过程*************\n");
prt(alg);
run=ready;
ready=ready->next;
run->state='R';
}
void timeslicecycle(char alg)〃时间片轮转法
{
while(run!=NULL)
{
run->cputime=run->cputime+t;// 处理时间加t run->needtime=run->needtime-t;// 完成需要时间减t run->round=run->round+t;// 运行完将其变为完成态,插入完成队列
if(run->needtime<=0)// 当进程完成时
{
run->next=finish;
finish=run;
run->state='F';
run=NULL;
if(ready匸NULL)//就绪队列不空,将第一个进程投入进行
firstin();
}
else
{
run->state='W';// 将进程插入到就绪队列中等待轮转
insert(run);// 将就绪队列的第一个进程投入运行
firstin();
}
prt(alg);
}
void main()// 主函数
{
char algo='P';// 算法标记
printf(" 输入进程的个数:");
scanf("%d",&N);// 输入进程数
printf(" 定义时间片大小:");
scanf("%d",&t);// 输入时间片大小
create(algo);// 创建进程
timeslicecycle(algo);// 时间片轮转法调度
}//main()
四、实验结果:
五、实验小结:
时间片轮转调度是一种最古老,最简单,最公平且使用最广的算法。
时间片轮转调度中关键的一点是时间片的长度的选取。
本实验可以自己设置时间片大小t,在试验过程中基本满足了实验要求。
通过本次实验,我更加了解了时间片轮转调度算法,通过翻看课本,对其的理解更加的深刻了,在以后的学习中,我会更加努力地学习操作系统的相关课程。
当然,实验中也遇到了问题,但都不是理论上的问题,而是编程的问题,根本原因还是编程基础不牢,以后会在编程方面加倍努力。