实用文档
XXXXXX计算机系综合性实验
实验报告
课程名称操作系统 B 实验学期 XXXX 至 XXXX 学年第 X 学期学生所在系部计算机系
年级 XXXX 专业班级 XXXXXX 学生 XXXX 学号 XXXXXXXXXXXX
任课教师 XXX 实验成绩
计算机系制
《操作系统B 》课程综合性实验报告
Y
run->count++; run->cputime++;run->needtime--;
run->needtime == 0
Y N N 将进程插入完成队列run->count== run->round
Y
将进程插入就绪队列
Flag=0
四、实验结果及分析
1.程序运行截图:
2.实验体会
(1)、本实验的难点是每执行一个时间片就让它排到队尾,也即重新排序,并从头开始调度执行!
(2)、时间片的工作流程是:时间片轮转的原则是系统将所有的就绪进程按照先来先服务的原则排成一个队列,每次调度时,把CPU分配队首进程,并令其执行一个时间片,当执行完时,有一个计时器发出时钟中断请求,该进程停止,并被送到就绪队列的末尾,然后再把处理机分配就绪队列的队列进程,同时也让它执行一个时间片。
(3)、通过亲手实验,对上述写的时间片的工作流程和原理有了更贴切的认识。另外本次实验遇到了很大的麻烦,其实大部分代码是借鉴网上的,但自己通过修改,来获取自己想要的,在自己的努力和同学的帮助下终于调试正确,很是高兴。
附代码:
#include
#include
#include
typedef struct node
{
char name[10]; //进程的名字
int round; //一次分配CPU的时间片
int cputime; //CPU已执行时间
int needtime; //进程执行所需要的时间
char state; //进程的状态,W-就绪态,R-执行态,F-完成态 int count; //记录进程执行的次数
struct node *next; //队列指针
}PCB;
PCB *ready=NULL,*run=NULL,*finish=NULL; //定义三个队列,就绪队列,执行队列和完成队列
int num;
void GetFirst(); //从就绪队列取得第一个节点
void Output(); //输出各队列信息
void InsertTime(PCB *in); //插入就绪片队列
void InsertFinish(PCB *in); //插入完成队列
void TimeCreate(); //时间片输入函数
void RoundRun(); //时间片轮转调度
void main()
{
printf("\n****** 欢迎光临指导 ******\n");
printf("\n****** 时间片轮转进程调度算法 ******\n");
printf("\n****** 计科B082 友 ******\n");
printf("\n****** 5 ******\n");
printf("\n****** 2011年5月15日 ******\n");
printf("\n请输入要创建的进程数目:\n");
scanf("%d",&num);
getchar(); //吸收回车符号
TimeCreate();
RoundRun();
Output();
}
void GetFirst() //取得第一个就绪队列节点
{
run = ready;
if(ready!=NULL)
{
run ->state = 'R';
ready = ready ->next;
run ->next = NULL;
}
}
void Output() //输出队列信息
{
PCB *p;
p = ready;
printf("进程轮数 cpu时间需要时间进程状态计数器\n");
while(p!=NULL)
{
printf("%s\t%d\t%d\t%d\t%c\t%d\n",p->name,p->round,p->cputime,p->needtim e,p->state,p->count);
p = p->next;
}
p = finish;
while(p!=NULL)
{
printf("%s\t%d\t%d\t%d\t%c\t%d\n",p->name,p->round,p->cputime,p->needtim e,p->state,p->count);
p = p->next;
}
p = run;
while(p!=NULL)
{
printf("%s\t%d\t%d\t%d\t%c\t%d\n",p->name,p->round,p->cputime,p->needtim e,p->state,p->count);
p = p->next;
}
}
void InsertTime(PCB *in) //将进程插入到就绪队列尾部
{
PCB *fst;
fst = ready;
if(ready == NULL)
{
in->next = ready;
ready = in;
}
else
{
while(fst->next != NULL)
{
fst = fst->next;
}
in ->next = fst ->next;
fst ->next = in;
}
}
void InsertFinish(PCB *in) //将进程插入到完成队列尾部{
PCB *fst;
fst = finish;
if(finish == NULL)
{
in->next = finish;
finish = in;
}
else
{
while(fst->next != NULL)
{
fst = fst->next;
}
in ->next = fst ->next;
fst ->next = in;
}
}
void TimeCreate() //时间片轮转输入函数
{
PCB *tmp;
int i;
printf("输入进程名字和进程时间片所需时间:\n"); for(i = 0;i < num; i++)
{
if((tmp = (PCB *)malloc(sizeof(PCB)))==NULL) {
perror("malloc");
exit(1);
}
scanf("%s",tmp->name);
getchar();
scanf("%d",&(tmp->needtime));
tmp ->cputime = 0;
tmp ->state ='W';
tmp ->round = 2; //假设每个进程所分配的时间片是2 tmp ->count = 0;
InsertTime(tmp);
}
}
void RoundRun() //时间片轮转调度算法
{
int flag = 1;
GetFirst();
while(run != NULL)
{
Output();
while(flag)
{
run->count++;
run->cputime++;
run->needtime--;
if(run->needtime == 0) //进程执行完毕
{
run ->state = 'F';
InsertFinish(run);
flag = 0;
}
else if(run->count == run->round)//时间片用完 {
run->state = 'W';
run->count = 0; //计数器清零,为下次做准备 InsertTime(run);
flag = 0;
}
}
flag = 1;
GetFirst();
}
}