操作系统实验报告进程调度算法.docx
《操作系统实验报告进程调度算法.docx》由会员分享,可在线阅读,更多相关《操作系统实验报告进程调度算法.docx(12页珍藏版)》请在冰豆网上搜索。
操作系统实验报告进程调度算法
操作系统实验报告
实验1进程调度算法
报告日期:
2016-6-10
姓名:
学号:
班级:
任课教师:
实验1进程调度算法
一、实验内容
按优先数调度算法实现处理器调度。
二、实验目的
在采用多道程序设计的系统中,往往有若干个进程同时处于就绪状态。
当就绪进程个数大于处理器数时,就必须依照某种策略来决定哪些进程优先占用处理器。
本实验模拟在单处理器情况下的处理器调度,帮助学生加深了解处理器调度的工作。
三、实验原理
设计一个按优先数调度算法实现处理器调度的程序。
(1)假定系统有五个进程,每一个进程用一个进程控制块PCB来代表,进程控制块的格式为:
进程名
指针
要求运行时间
优先数
状态
其中,进程名——作为进程的标识,假设五个进程的进程名分别为P1,P2,P3,P4,P5。
指针——按优先数的大小把五个进程连成队列,用指针指出下一个进程的进程控制块的首地址,最后一个进程中的指针为“0”。
要求运行时间——假设进程需要运行的单位时间数。
优先数——赋予进程的优先数,调度时总是选取优先数大的进程先执行。
状态——可假设有两种状态,“就绪”状态和“结束”状态。
五个进程的初始状态都为“就绪”,用“R”表示,当一个进程运行结束后,它的状态为“结束”,用“E”表示。
(2)在每次运行你所设计的处理器调度程序之前,为每个进程任意确定它的“优先数”和“要求运行时间”。
(3)为了调度方便,把五个进程按给定的优先数从大到小连成队列。
用一单元指出队首进程,用指针指出队列的连接情况。
例:
队首标志
K2
K1
P1
K2
P2
K3
P3
K4
P4
K5
P5
0
K4
K5
K3
K1
2
3
1
2
4
1
5
3
4
2
R
R
R
R
R
PCB1
PCB2
PCB3
PCB4
PCB5
(4)处理器调度总是选队首进程运行。
采用动态改变优先数的办法,进程每运行一次优先数就减“1”。
由于本实验是模拟处理器调度,所以,对被选中的进程并不实际的启动运行,而是执行:
优先数-1
要求运行时间-1
来模拟进程的一次运行。
提醒注意的是:
在实际的系统中,当一个进程被选中运行时,必须恢复进程的现场,让它占有处理器运行,直到出现等待事件或运行结束。
在这里省去了这些工作。
(5)进程运行一次后,若要求运行时间≠0,则再将它加入队列(按优先数大小插入,且置队首标志);若要求运行时间=0,则把它的状态修改成“结束”(E),且退出队列。
(6)若“就绪”状态的进程队列不为空,则重复上面(4)和(5)的步骤,直到所有进程都成为“结束”状态。
(7)在所设计的程序中应有显示或打印语句,能显示或打印每次被选中进程的进程名以及运行一次后进程队列的变化。
(8)为五个进程任意确定一组“优先数”和“要求运行时间”,启动所设计的处理器调度程序,显示或打印逐次被选中进程的进程名以及进程控制块的动态变化过程。
四、实验内容
1.画出算法流程图
2.程序中使用的数据结构及符号说明。
1>结构体
typedefstructPCB//封装进程结构体
{
charname[2];
inttime;
intprior_num;
charstate;
structPCB*next;
}PCB,*pPCB;//结构体名为PCB,pPCB是指向结构体的指针
2>链表
pPCBCreateLink(PCB*arr)
{
inti=0;
intj=0;
intpos=0;
intpos1=0;
pPCBhead=NULL;
for(i=0;i{
if(arr[i].prior_num==N)
{
pos=i;
break;
}
}
head=&arr[pos];
for(i=N-1;i>0;i--)//按优先级大小依次找到其他进程,链起来
{
for(j=0;j{
if(arr[j].prior_num==i)
{
pos1=j;
break;
}
}
arr[pos].next=&arr[pos1];
pos=pos1;
}
returnhead;//返回头结点
}
3.源程序
#define_CRT_SECURE_NO_WARNINGS1
#ifndef_SCHEDULING_H__
#define_SCHEDULIHG_H__
#defineN5
#include
#include
#include
#include
typedefstructPCB//封装进程结构体
{
charname[2];
inttime;
intprior_num;
charstate;
structPCB*next;
}PCB,*pPCB;//结构体名为PCB,pPCB是指向结构体的指针
pPCBCreateLink(PCB*arr);//创建链表把5个进程链起来
voidInitPCB(PCB*arr,int*a);//初始化进程
pPCBrunPCB(PCB*arr,pPCBpcb);//进程运行
voidprintPCB(PCB*arr);//输出进程的初始状态
voidrandom(inta[],intn);//将数组内容打乱顺序
voidPrintRun(pPCBhead);//输出运行后的进程
#endif
#include"head.h"
voidrandom(inta[],intn)
{
intindex,tmp,i;
srand((unsignedint)time(NULL));
for(i=0;i{
index=rand()%(n-i)+i;
if(index!
=i)
{
tmp=a[i];
a[i]=a[index];
a[index]=tmp;
}
}
}
pPCBCreateLink(PCB*arr)
{
inti=0;
intj=0;
intpos=0;
intpos1=0;
pPCBhead=NULL;
for(i=0;i{
if(arr[i].prior_num==N)
{
pos=i;
break;
}
}
head=&arr[pos];
for(i=N-1;i>0;i--)//按优先级大小依次找到其他进程,链起来
{
for(j=0;j{
if(arr[j].prior_num==i)
{
pos1=j;
break;
}
}
arr[pos].next=&arr[pos1];
pos=pos1;
}
returnhead;//返回头结点
}
voidInitPCB(PCB*arr,int*a)
{
inti=0;
char*str[]={"p1","p2","p3","p4","p5"};
for(i=0;i{
strcpy(arr[i].name,str[i]);
arr[i].prior_num=a[i];
arr[i].state='R';
arr[i].next=NULL;
arr[i].time=(rand()%4)+1;//这里将所需运行时间控制在4以内
}
}
voidprintPCB(PCB*arr)//打印进程最初状态
{
inti=0;
for(i=0;i{
printf("进程名称:
%s\n",arr[i].name);
printf("进程优先级:
%d\n",arr[i].prior_num);
printf("进程所需运行时间:
%d\n",arr[i].time);
printf("进程当前状态:
%c\n",arr[i].state);
printf("\n");
}
}
pPCBrunPCB(pPCBhead,pPCBpcb)//进程执行函数
{
inti=0;
pPCBcur=head;
pPCBprev=NULL;
while(cur)
{
cur->time--;//先让进程的时间和优先级减一
cur->prior_num--;
if(cur->time==0)//判断所需运行时间是否为0
{
if(cur==head)//判断是否是头结点
{
cur->state='E';
head=head->next;
cur=head;
}
else
{
cur->state='E';
prev->next=cur->next;
cur=cur->next;
}
}
else//若时间不为0,指针向后移动
{
prev=cur;
cur=cur->next;
}
}
returnhead;
}
voidPrintRun(pPCBhead)
{
pPCBcur=head;
printf("进程运行:
\n");
while(cur)
{
printf("进程名称:
%s\n",cur->name);
printf("进程优先级:
%d\n",cur->prior_num);
printf("所需运行时间:
%d\n",cur->time);
printf("当前状态:
%c\n",cur->state);
printf("\n");
cur=cur->next;
}
}
#include"head.h"
intmain()
{
PCBpcb;
pPCBhead;
inta[]={1,2,3,4,5};
random(a,N);
PCBarr[N];
InitPCB(arr,a);
printPCB(arr);
head=CreateLink(arr);
printf("运行一次:
\n");
head=runPCB(head,&pcb);
PrintRun(head);
printf("运行二次:
\n");
head=runPCB(head,&pcb);
PrintRun(head);
printf("运行三次:
\n");
head=runPCB(head,&pcb);
PrintRun(head);
getchar();
return0;
}
4.程序运行时的初值和运行结果
初始状态:
运行一次:
运行两次:
运行三次:
五、实验小结
在用程序模拟实现进程的优先数调度过程中,我对操作系统的进程调度理解也越来越深刻,不断的调试BUG让我很有成就感,同时,这个实验花费了我大量时间让我觉得我还需要有进一步的提升。