使用动态优先权的进程调度算法的模拟实验.docx

上传人:b****0 文档编号:12853033 上传时间:2023-04-22 格式:DOCX 页数:20 大小:291.21KB
下载 相关 举报
使用动态优先权的进程调度算法的模拟实验.docx_第1页
第1页 / 共20页
使用动态优先权的进程调度算法的模拟实验.docx_第2页
第2页 / 共20页
使用动态优先权的进程调度算法的模拟实验.docx_第3页
第3页 / 共20页
使用动态优先权的进程调度算法的模拟实验.docx_第4页
第4页 / 共20页
使用动态优先权的进程调度算法的模拟实验.docx_第5页
第5页 / 共20页
点击查看更多>>
下载资源
资源描述

使用动态优先权的进程调度算法的模拟实验.docx

《使用动态优先权的进程调度算法的模拟实验.docx》由会员分享,可在线阅读,更多相关《使用动态优先权的进程调度算法的模拟实验.docx(20页珍藏版)》请在冰豆网上搜索。

使用动态优先权的进程调度算法的模拟实验.docx

使用动态优先权的进程调度算法的模拟实验

使用动态优先权的进程调度算法的模拟实验

1.实验目的

通过动态优先权算法的模拟加深对进程概念和进程调度过程的理解。

2.实验内容

(1)用C语言实现对N个进程采用动态优先权优先算法的进程调度;

(2)每个用来标识进程的进程控制块PCB用结构来描述,包括以下字段:

●进程标识数;

●进程优先数priority,并规定优先数越大的进程,其优先权越高;

●进程已占用的CPU时间cputime;

●进程还需占用的CPU时间alltime,当进程运行完毕时,alltime变为0;

●进程的阻塞时间startblock,表示当进程再运行startblock个时间片后,进程将进入阻塞状态;

●进程被阻塞的时间blicktime,表示已阻塞的进程再等待blocktime个时间片后,将转换为就绪态;

●进程状态state;

●队列指针next,用来将PCB排成队列。

(3)优先数改变的原则:

●进程在就绪队列中呆一个时间片,优先数增加1.

●进程每运行一个时间片,优先数减3。

(4)假设在调度前,系统中有5个进程,它们得初始状态如下:

ID01234

PRIORITY93830290

CPUTIME00000

ALLTIME33634

STARTBLOCK2-1-1-1-1

BLOCKTIME30000

STATEREADYREADYREADYREADYREADY

(5)为了清楚地观察诸进程的调度过程,程序应将每个时间片内的进程的情况显示出来,参照的具体格式如下:

RUNNINGPROG:

i

READY_QUEUE:

->id1->id2

BLOCK_QUEUE:

->id3->id4

======================================================================

ID01234

PRIORITYP0P1P2P3P4

CPUTIMEC0C1C3C4C5

ALLTIMEA0A1A2A3A4

STARTBLOCKT0T1T2T3T4

BLOCKTIMEB0B1B2B3B4

STATES0S1S2S3S4

开始

创建就绪队列

Alltime>0

就绪→执行

显示状态

改变优先数

P.alltime-1

P.cuptime+1

P.alltime==0

P.startblock>0

P.startblock-1

P.startblock==0

执行→阻塞

执行→就绪

BLK==NULL

P.blocktime-1

P.blocktime==0

阻塞→就绪

结束

3.过程(流程图)

 

4.代码

#include

#include

#include

typedefstructnode

{

intid;//进程标识数

intpriority;//进程优先数,优先数越大优先级越高

intcputime;//进程已占用的CPU时间

intalltime;//进程还需占用的CPU时间

intstartblock;//进程的阻塞时间

intblocktime;//进程被阻塞的时间

charstate[10];//进程状态

structnode*next;//队列指针

}PCB;

PCB*CreatQueue(intnum)//创建一个就绪队列

{

inti;//i为循环计数器

PCB*head,*temp1,*temp2,*temp3;//head为就绪队列的头指针,temp1为创建进程结点的指针,temp2、temp3分别为比较结点的前驱结点和比较结点

for(i=0;i

{

temp1=(PCB*)malloc(sizeof(PCB));

printf("输入第%d个进程的(id…state)\n",i);

scanf("%d%d%d%d%d%d%s",&temp1->id,&temp1->priority,&temp1->cputime,&temp1->alltime,&temp1->startblock,&temp1->blocktime,temp1->state);

if(i==0)//如果创建的是第一个结点

{

head=temp1;

head->next=NULL;

continue;

}

if(head->prioritypriority)//如果创建结点中所保存的数比头结点所保存的数要大,则直接把该结点插入到头结点之前

{

temp1->next=head;

head=temp1;

continue;

}

temp2=head;//temp2为比较结点的直接前驱结点

temp3=temp2->next;//temp3为比较的结点

while(temp3!

=NULL&&temp3->priority>=temp1->priority)//实现查找的功能

{

temp2=temp3;

temp3=temp2->next;

}

temp2->next=temp1;

temp1->next=temp3;

}

returnhead;

}

PCB*InsertQueue(PCB*head,PCB*run)//在就绪队列中插入一个结点

{

PCB*temp1,*temp2;//temp1和temp2分别为比较结点的前驱和比较结点

if(head==NULL)//如果就绪队列为空

{

head=run;

head->next=NULL;

}

elseif(head->prioritypriority)//如果插入结点中所保存的数比头结点所保存的数要大,则直接把该结点插入到头结点之前

{

run->next=head;

head=run;

}

else

{

temp1=head;//temp1为比较结点的直接前驱结点

temp2=temp1->next;//temp2为比较的结点

while(temp2!

=NULL&&temp2->priority>=run->priority)//实现查找的功能

{

temp1=temp2;

temp2=temp1->next;

}

temp1->next=run;

run->next=temp2;

}

returnhead;

}

main()

{

intnum;//num为进程的个数

intalltime=0;//用来保存所有进程需要占用的CPU时间

PCB*head;//head为就绪队列的头指针

PCB*run=NULL;//run为执行进程结点的指针

PCB*block=NULL;//block为阻塞进程的结点

PCB*temp;

printf("请输入进程的个数:

");

scanf("%d",&num);

head=CreatQueue(num);

getchar();

temp=head;

while(temp!

=NULL)

{

alltime+=temp->alltime;

temp=temp->next;

}

while(alltime>0)

{

if(head!

=NULL)

{

run=head;//把就绪队列中的第一个进程取出来执行

head=head->next;//就绪队列的头指针指向下一个结点

strcpy(run->state,"run");//状态改为执行

run->next=NULL;

/*显示状态*/

printf("RUNNINGPROG:

%d\n",run->id);//显示执行进程

printf("READY_QUEUE:

");//显示就绪进程

temp=head;

while(temp!

=NULL)

{

printf("->%d",temp->id);

temp=temp->next;

}

printf("\n");

printf("BLOCK_QUEUE:

");//显示阻塞进程

if(block!

=NULL)

{

printf("%d",block->id);

}

printf("\n");

printf("============================================================================\n");

printf("IDPRIORITYCPUTIMEALLTIMESTARTBLOCKBLOCKTIMESTATE\n");

printf("%d%d%d%d%d%d%s\n",run->id,run->priority,run->cputime,run->alltime,run->startblock,run->blocktime,run->state);

temp=head;

while(temp!

=NULL)

{

printf("%d%d%d%d%d%d%s\n",temp->id,temp->priority,temp->cputime,temp->alltime,temp->startblock,temp->blocktime,temp->state);

temp=temp->next;

}

if(block!

=NULL)

{

printf("%d%d%d%d%d%d%s",block->id,block->priority,block->cputime,block->alltime,block->startblock,block->blocktime,block->state);

}

printf("\n");

printf("============================================================================\n");

/*显示状态*/

/*改变优先数*/

run->priority-=3;//执行进程的优先数减3

temp=head;

while(temp!

=NULL)//就绪进程的优先数加1

{

temp->priority+=1;

temp=temp->next;

}

/*改变优先数*/

/*改变执行进程的有关参数*/

run->cputime+=1;//执行进程的已占用CPU时间加1

run->alltime-=1;//还需要的CPU时间减1

if(run->alltime!

=0)

{

if(run->startblock>0)//如果该进程会被阻塞

{

run->startblock-=1;//执行完一个时间片后,开始阻塞的时间减1

if(run->startblock==0)//如果阻塞的时间到了

{

block=run;//执行转阻塞

strcpy(block->state,"b");//状态转阻塞

alltime--;

printf("\n");

continue;

}

}

strcpy(run->state,"r");//状态转就绪

head=InsertQueue(head,run);//执行转就绪

run=NULL;

}

/*改变执行进程的有关参数*/

alltime--;

}

else

{

/*显示状态*/

printf("RUNNINGPROG:

\n");//显示执行进程

printf("READY_QUEUE:

\n");//显示就绪进程

printf("BLOCK_QUEUE:

");//显示阻塞进程

if(block!

=NULL)

{

printf("%d",block->id);

}

printf("\n");

printf("============================================================================\n");

printf("IDPRIORITYCPUTIMEALLTIMESTARTBLOCKBLOCKTIMESTATE\n");

if(block!

=NULL)

{

printf("%d%d%d%d%d%d%s",block->id,block->priority,block->cputime,block->alltime,block->startblock,block->blocktime,block->state);

}

printf("\n");

printf("============================================================================\n");

/*显示状态*/

}

/*改变阻塞进程的有关参数*/

if(block!

=NULL)//如果有阻塞进程

{

block->blocktime-=1;//被阻塞的时间减1

if(block->blocktime==0)//如果被阻塞的时间到了

{

strcpy(block->state,"r");//状态转就绪

head=InsertQueue(head,block);//阻塞转就绪

block=NULL;

}

}

/*改变阻塞进程的有关参数*/

getchar();

}

}

 

5.运行结果

输入5个进程,分别是0—4进程,运行结果可以看到第一次运行进程1,优先数为38。

第二次运行的进程是进程1,优先数为35,cpu时间占用为1,进程所需时间为2,

同时下一个进程(进程1)的优先数+1。

第三次运行进程2,优先数32,cpu占用时间将+1,所需时间将-1。

同时下一个进程(进程1)优先数+1,。

第四次运行进程1,优先数33,cpu占用时间2+1,所需时间将-1。

同时下一个进程(进程3)优先数+1,

第四次运行进程1完毕,所需时间为0。

进程1运行完毕。

第五次运行进程3,优先数33,cpu占用时间0将+1,所需时间3将-1。

同时下一个进程(进程2)优先数+1。

第六次运行进程2,优先数31将-3,cpu占用时间1将+1,所需时间5将-1。

同时下一个进程(进程3)优先数+1。

第七次运行进程3,优先数31将-3,cpu占用时间1将+1,所需时间2将-1。

同时下一个进程(进程2)优先数+1。

第八次运行进程2,优先数29将-3,cpu占用时间2将+1,所需时间4将-1。

同时下一个进程(进程3)优先数+1。

第九次运行进程3,优先数29将-3,cpu占用时间2将+1,所需时间1将-1。

同时下一个进程(进程2)优先数+1。

第九次运行完毕,进程3的所需时间为0,进程3运行完毕。

第十次运行进程2,优先数27将-3,cpu占用时间3将+1,所需时间3将-1。

同时下一个进程(进程0)优先数+1。

第十一次运行进程2,优先数24将-3,cpu占用时间4将+1,所需时间2将-1。

同时下一个进程(进程0)优先数+1。

第十二次运行进程2,优先数21将-3,cpu占用时间5将+1,所需时间1将-1。

同时下一个进程(进程0)优先数+1。

第十二次运行完毕,进程2所需时间为0,进程2运行完毕。

第十三次运行进程0,优先数21将-3,cpu占用时间0将+1,所需时间3将-1。

同时下一个进程(进程4)优先数+1。

第十四次运行进程0,优先数18将-3,cpu占用时间1将+1,所需时间2将-1。

同时下一个进程(进程4)优先数+1。

第十五次运行进程4,优先数14将-3,cpu占用时间0将+1,所需时间4将-1。

同时下一个进程(进程0)优先数+1。

第十六次运行进程4,优先数11将-3,cpu占用时间1将+1,所需时间3将-1。

同时下一个进程(进程0)优先数+1。

第十七次运行进程4,优先数8将-3,cpu占用时间2将+1,所需时间2将-1。

同时下一个进程(进程0)优先数+1。

第十八次运行进程0,优先数15将-3,cpu占用时间2将+1,所需时间1将-1。

同时下一个进程(进程4)优先数+1。

第十八次运行完毕,进程0所需时间为0,进程0运行完毕。

第十九次运行进程4,优先数6将-3,cpu占用时间3将+1,所需时间1将-1。

第二十次运行进程4,优先数6将-3,cpu占用时间3将+1,所需时间1将-1。

第二十次运行完毕,进程4所需时间为0,进程4运行完毕。

所有进程运行完毕。

5.总结

本次试验感觉难度比较大,有很多生疏的指令。

但在老师和同学的帮助下都解决了。

 总体上还是对进程概念和进程调度过程有了一个更深的理解。

在这次试验中也暴露出自己不少的缺点,希望以后试验中可以改正!

 

本文利用C 语言对动态优先权的进程调度算法进行了设计和模拟实现。

程序可实现动态的进行各个进程相关信息的录入, 如CPUTIME、ALLTIME、STARTBLOCK、BLOCKTIME 等信息。

并充分考虑了进程在执行过程中可能发生的多种情况, 更好的体现了进程的就绪态、执行态、阻塞态三者之间的关系以及相互的转换。

程序的运行过程清晰的体现了动态优先权的调度算法的执行过程, 有利于加深对算法的理解和掌握。

由于抢占式调度算法与硬件密切相关, 由软件实现非常困难, 所以本程序实现的是非抢占式的动态优先权进程调度算法。

抢占式的动态优先权进程调度算法的模拟实现有待于进一步研究

 

6、思考题 

(1)在实际的调度中,除了按调度算法选择下一个执行的进程外,还应处理哪些工作?

 

答:

1.记录系统中所有进程的执行情况 

作为进程调度的准备,进程管理模块必须将系统中各个进程的执行特征记录在各个进程的PCB表中。

 

2.进行进程上下文交换 

一个进程的上下文包括进程的状态,有关变量和数据结构的值。

机器寄存器的值和PCB以及有关程序,数据等。

 

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1