单处理器系统的进程调度.docx
《单处理器系统的进程调度.docx》由会员分享,可在线阅读,更多相关《单处理器系统的进程调度.docx(19页珍藏版)》请在冰豆网上搜索。
单处理器系统的进程调度
一.一、 单处理器系统的进程调度
1.实验目的
在采用多道程序设计的系统中,往往有若干个进程同时处于就绪状态。
当就绪进程个数大于处理器数时,就必须依照某种策略来决定哪些进程优先占用处理器。
本实验模拟在单处理器情况下的处理器调度,帮助学生加深了解处理器调度的工作。
2.实验内容与要求
(1)设计多个进程并发执行的模拟调度程序,每个程序由一个PCB表示。
(2)模拟调度程序可任选两种调度算法之一实现。
(3)程序执行中应能在屏幕上显示出各进程的状态变化,以便于观察调度的整个过程。
3.实验说明
设计一个按优先数调度算法实现处理器调度的程序。
(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)为五个进程任意确定一组“优先数”和“要求运行时间”,启动所设计的处理器调度程序,显示或打印逐次被选中进程的进程名以及进程控制块的动态变化过程。
4.实验步骤
本次实验的思想是,首先将实验给定的五个进程分别用一个进程控制块PCB来代表,其实现方法是用一个结构体类型来表示,在此结构体中分别有进程名、进程要求运行时间、进程优先级、进程状态和指向下一个进程控制块的指针,其
定义如下:
typedefstructPCB
{
intid;进程名字p1、p2、p3、p4、p5
structPCB*next;指针,指示下一个进程位置
intruntime;进程要求运行时间
intpriority;进程的优先级
charstatus;进程状态R或E,结束或是就绪
}*pcb;
在这之后便是创建预先队列,方法是将进程按照给定的优先级从大到小构成一个优先队列。
这样做的原因是在进行进程调用时,是系统是按照其优先级由大到小的顺序进行调用的,每次被调用的总是优先级数最大的进程,所以应该将事先给定的五个进程由大到小安排(按优先级)。
其实现方法是首先创建链表表头,之后依次将优先级最大的进程插入至表头之后。
数据结构如下:
voidcreate(PCB*head)
{
inta,b;a为进程要求运行时间,b为进程优先级
head->next=NULL;
for(inti=1;i=5;i++)
{
cout<<"-------P"<
"<cin>>a>>b;
PCB*p=newPCB;
PCB*q=h->next;输入进程信息
p->id=i;
p->runtime=a;
p->priority=b;
p->status='R';
while((q==NULL)||(p->priority>q->priority))
{如果输入进程优先级
p->next=head->next;大于第一个进程优先级,
head->next=p;将其插入头指针之后
}
while((p->prioritynext->priority)&&(q->next!
=NULL))
{
q=q->next;如不是,
}那么寻找
p->next=q->next;第一个
q->next=p;优先级
}小于输入
}进程的进程,将输入进程插入其之前
队首标志
创建优先队列后,当系统调用其中一个进程时,因为本程序是模拟进程调用,所以只需在程序模拟调用后将被调用的进程进行修改即:
将优先数减1,将要求运行时间减1。
其次,如果在结束依次进程调用后发现某进程的要求运行时间大于0时,则将该进程的状态设为就绪,同时按优先级大小加入到优先队列中(初始时创建的链表中即就绪队列),反之如果发现某进程的优先级等于0时,则将它的状态修改为结束,同时将它从优秀队列中删除。
其实现方法是按排序方法将修改后的进程插入优先队列,其数据结如下:
voidsort(PCB*head)
{
PCB*p=head->next;
head->next=p->next;首先将优先级最大的进程从优先队列中脱离出来
PCB*q=head->next;
if(head->next->runtime==0)
{
head->next->status='E';如果进程要求运行时间为0则将
head->next=head->next->next;其状态改为“E”,并从优先队列
return;中删除
}
if((q==NULL)||(p->priority>q->priority))
{
p->next=head->next;
head->next=p;
return;
}
while((q->next!
=NULL)&&(p->priority<=q->next->priority))
{
q=q->next;
}
p->next=q->next;
q->next=p;
}
5.实验流程
不考虑head
NY
N
Y
Y
YN
6.实验结果
i进程控制块的初始状态:
ii
(1)选中p5,选中后的进程控制块状态如下:
P4
P5
P3
P2
P1
P5
P3
P2
P1
null
5
5
4
3
2
4
4
3
2
1
R
R
R
R
R
PCB1
PCB2
PCB3
PCB4
PCB5
(2)选中进程p4,选中后进程控制块状态如下:
P5
P3
P4
P2
P1
P3
P4
P2
P1
null
5
4
4
3
2
4
3
3
2
1
R
R
R
R
R
PCB1
PCB2
PCB3
PCB4
PCB5
(3)选中进程p5,选中后进程控制块状态如下:
P3
P4
P5
P2
P1
P4
P5
P2
P1
null
4
4
4
3
2
3
3
3
2
1
R
R
R
R
R
PCB1
PCB2
PCB3
PCB4
PCB5
(4)选中进程p3,选中后进程控制块状态如下:
P4
P5
P3
P2
P1
P5
P3
P2
P1
null
4
4
3
3
2
3
3
2
2
1
R
R
R
R
R
PCB1
PCB2
PCB3
PCB4
PCB5
其余略……
以下依程序执行方式显示:
7.实验源程序
#include
typedefstructPCB
{
intid;
structPCB*next;
intruntime;
intpriority;
charstatus;
}*pcb;
voidcreate(PCB*h)
{
h->next=NULL;
inta,b;
for(inti=0;i<5;i++)
{
cout<<"-------P"<
"<cin>>a>>b;
PCB*p=newPCB;
PCB*q=h->next;
p->id=i+1;
p->runtime=a;
p->priority=b;
p->status='R';
if((q==NULL)||(p->priority>q->priority))
{
p->next=h->next;
h->next=p;
continue;
}
while((p->prioritynext->priority)&&(q->next!
=NULL))
{
q=q->next;
}
p->next=q->next;
q->next=p;
}
}
voidsort(PCB*h)
{
if(h->next->runtime==0)
{
h->next->status='E';
h->next=h->next->next;
return;
}
PCB*p=h->next;
h->next=p->next;
PCB*q=h->next;
if((q==NULL)||(p->priority>q->priority))
{
p->next=h->next;
h->next=p;
return;
}
while((q->next!
=NULL)&&(p->priority<=q->next->priority))
{
q=q->next;
}
p->next=q->next;
q->next=p;
}
voidcall(PCB*h)
{
cout<<"$$$调用P"<next->id<h->next->runtime--;
h->next->priority--;
}
voidshow(PCB*h)
{
PCB*p=h->next;
while(p!
=NULL)
{
cout<<"p"<id<<""<runtime<<""<priority<<""<status<cout<<"----------------------------------------------------------------------"<p=p->next;
}
}
voidmain()
{
cout<<************************<cout<<"**请输入各个进程的运行时间及其优先级**"<create(h);
while(h->next!
=NULL)
{
call(h);
sort(h);
show(h);
}
}