实验二——动态高优先权优先调度算法
动态高优先权
动态高优先权实验报告一、实验目的通过动态优先权算法的模拟加深对进程概念和进程调度过程的理解.提高自己的动手能力主要是通过自己去思考并自己的编码更进一步及更贴切的去理解弄明白动态优先权算法的模拟加深对进程概念和进程调度过程的工作流程及其原理!二、实验要求用C语言来实现对N个进程采用动态优先权优先算法的进程调度。
三、实验内容每个用来标识进程的进程控制块PCB用结构来描述,包括以下字段:1.进程标识数ID2.进程优先数PRIORITY,并规定优先数越大的进程,其优先权越高。
3.进程已占用的CPU时间CPUTIME。
4.进程还需占用的CPU时间ALLTIME。
当进程运行完毕时,ALLTIME变为0。
5.进程的阻塞时间STARTBLOCK,表示当进程再运行STARTBLOCK个时间片后,进程将进入阻塞状态。
6.进程被阻塞的时间BLOCKTIME,表示已阻塞的进程再等待BLOCKTIME个时间片后,将转换成就绪状态。
7.进程状态STATE。
8.队列指针NEXT,用来将PCB排成队列。
四、实验结果五、实验小结其实每次实验,老师都建议大家自己开始写程序,网上的代码可以自己选择性的参考,但绝对不能纯粹性的抄袭,但由于自己的C++基础实在是不怎么好,如果自己编的话会摸不着头脑,不知从哪里开始,就还是从网上下载了一些代码,在同学们的帮助下,理解编着的思路,明白各个模块的调度,也明白了动态高优先权的具体内容。
虽然中间碰见了不少问题,但经过多次调试,还是有了比较满意的结果。
然而这些调试是需要花费时间的,课堂的时间不够,只能课下去完成。
正所谓皇天不负有心人,努力就会有收获,经过这次试验也算是有所提高吧。
动态优先权是指在创建进程时所赋予的优先权,可以随进程的推进或随其等待时间的增加而改变的,以便获得更好的调度性能.例如,我们可以规定,在就绪队列中的进程,随其等待时间的增长,其优先权以速率a 提高.若所有的进程都具有相同的优先权初值,则显然是最先进入就绪队列的进程,将因其动态优先权变得最高而优先获得处理机,此即FCFS算法.优先权的变化规律可描述为:由于等待时间与服务时间之和,就是系统对该作业的响应时间,故该优先权又相当于响应比RP此次实验让我明白了许多,不仅是知识上的,还有认识上的,我明白任何时候都是自己动手丰衣足食,学问是自己的,是无止境的,为了以后我们只能努力的补充自己···附录#include "stdio.h"#include <stdlib.h>#include <conio.h>#define getpch(type) (type*)malloc(sizeof(type))#define NULL 0struct pcb { /* 定义进程控制块PCB */char name[10]; /*定义进程名称*/char state; /*进程状态*/int super; /*优先数*/int ntime; /*需要运行的时间*/int rtime; /*已占用的CPU时间*/struct pcb* link;}*ready=NULL,*p;typedef struct pcb PCB; /*pcb表*/void sort() /* 建立对进程进行优先级排列函数*/{ PCB *first, *second;int insert=0;if((ready==NULL)||((p->super)>(ready->super))) /*优先级最大者, 插入队首*/{ p->link=ready;ready=p;}else /* 进程比较优先级,插入适当的位置中*/{ first=ready;second=first->link;while(second!=NULL){ if((p->super)>(second->super)) /*若插入进程比当前进程优先数大,*/{ /*插入到当前进程前面*/p->link=second;first->link=p;second=NULL;insert=1;}else /* 插入进程优先数最低,则插入到队尾*/{ first=first->link;second=second->link;}}if(insert==0) first->link=p;}}void input() /* 建立进程控制块函数*/ { int i,num;system("cls"); /*清屏*/printf("\n 请输入进程号?");scanf("%d",&num);for(i=0;i<num;i++){ printf("\n 进程号No.%d:\n",i);p=getpch(PCB);printf("\n 输入进程名:");scanf("%s",p->name);printf("\n 输入进程优先数:");scanf("%d",&p->super);printf("\n 输入进程运行时间:");scanf("%d",&p->ntime);printf("\n");p->rtime=0;p->state='w';p->link=NULL;sort(); /* 调用sort函数*/}}int space(){ int l=0; PCB* pr=ready;while(pr!=NULL){ l++;pr=pr->link;}return(l);}void disp(PCB * pr) /*建立进程显示函数,用于显示当前进程*/{ printf("\n qname \t state \t super \t ndtime \t runtime \n");printf("|%s\t",pr->name);printf("|%c\t",pr->state);printf("|%d\t",pr->super);printf("|%d\t",pr->ntime);printf("|%d\t",pr->rtime);printf("\n");}void check() /* 建立进程查看函数,检查等待队列的进程是否进入就绪队列*/{ PCB* pr;printf("\n **** 当前正在运行的进程是:%s",p->name); /*显示当前运行进程*/disp(p);pr=ready;printf("\n ****当前就绪队列状态为:\n"); /*显示就绪队列状态*/while(pr!=NULL){ disp(pr);pr=pr->link;}}void destroy() /*建立进程撤消函数(进程运行结束,撤消进程)*/{ printf("\n 进程[%s] 已完成.\n",p->name);free(p);}void running() /* 建立进程就绪函数(进程运行时间到,置就绪状态*/ { (p->rtime)++;if(p->rtime==p->ntime)destroy(); /* 调用destroy函数*/else{ (p->super)--;p->state='w';sort(); /*调用sort函数*/}}void main() /*主函数*/{ int len, h=0;char ch;input();len=space();while((len!=0)&&(ready!=NULL)){ ch=getchar();h++;printf("\n The execute number:%d \n",h); p=ready;ready=p->link;p->link=NULL;p->state='R';check();running();printf("\n 按任一键继续......");ch=getchar();}printf("\n\n 进程已经完成.\n");ch=getchar();}。
使用动态优先权的进程调度算法的模拟实验
使用动态优先权的进程调度算法的模拟实验动态优先权调度算法是一种根据进程动态表现调整优先权的进程调度算法。
它不仅考虑了进程的优先级,还将进程的实际执行情况作为调度依据。
下面将介绍一个模拟实验,以更好地理解这种调度算法。
实验背景:假设有五个待执行的进程,它们的ID和初始优先权分别为P1(3)、P2(5)、P3(2)、P4(1)、P5(4)。
这五个进程的优先权在调度过程中会根据实际情况进行动态调整。
实验过程:1.初始化:在实验开始之前,首先需要对进程的初始状态进行初始化。
每个进程有两个属性:优先级和已运行时间。
优先级用于决定进程的调度优先级,已运行时间用于记录进程已经运行了多长时间。
设置一个全局时间片,表示每个时间单元中运行的时间。
2.进程调度:根据进程的优先权,选取最高优先权的进程进行调度。
从P1到P5,进程的优先权逐渐减小。
-选择进程:比如初始时最高优先权的进程为P2-进程执行:进程P2被调度后开始执行,运行一个时间片。
每运行一个时间片,该进程的已运行时间加一,重新计算进程的优先权。
-优先权调整:根据已运行时间的加一,重新计算进程的优先权。
优先权的计算公式可以根据实际需要进行调整,比如可以设为:新的优先权=原优先权+(已运行时间/其中一常量)。
-进程阻塞:如果进程运行的时间超过了一个时间片,则该进程被阻塞,进入就绪队列等待下一次轮转调度,其他进程继续执行。
3.调度进程更新:进程在执行和阻塞的过程中,它们的优先权会发生变化。
在每一轮调度后,需要更新进程的优先权,重新确定每个进程的调度顺序。
4.实验结果:重复进行步骤2和步骤3,直到所有进程都完成执行。
记录每次调度过程中的结果,包括进程的执行顺序、时刻和优先权的变化。
实验分析:通过模拟实验,可以得出以下一些结论:1.动态优先权调度算法能够根据实际情况调整进程的优先权,更好地适应不同进程的需求,增强了调度的灵活性。
2.在实验中,进程运行时间越长,优先权越低。
动态高优先权实验报告
实验一动态高优先权调度实验一、实验目的:通过动态优先权算法的模拟加深对进程概念和进程调度过程的理解.提高自己的动手能力主要是通过自己去思考并自己的编码更进一步及更贴切的去理解弄明白动态优先权算法的模拟加深对进程概念和进程调度过程的工作流程及其原理!二.实验要求:1.在开是页面用户需要输入作业名,优先权级数,作业要求服务时间;2.每运行一个时间单位,作业的优先权级数减去自己的学号的后两位31mod5=1;3.在运行出的用户界面中需显示初始作业名,作业状态,优先权级数,需要服务的时间,已经运行的时间;4.每次调度前后显示作业队列。
三.实验内容利用C语言或JAVA或其它的语言(我用的用C语言)来实现对N 个进程采用动态优先权优先算法的进程调度。
每个用来标识进程的进程控制块PCB用结构来描述,包括以下字段:进程标识数ID进程优先数,并规定优先数越大的进程,其优先权越高进程已占用的CPU时间CUPTIME 进程还需占用的CPU时间ALLTIME。
当进程运行完毕时,ALLTIME变为0进程的阻塞时间STARTBLOCK,表示当进程再运行STARTBLOCK个时间片后,进程将进入阻塞状态。
进程被阻塞的时间BLOCKTIME,表示已阻塞的进程再等待BLOCKTIME个时间片后,将转换成就绪状态。
进程状态STATE.队列指针NEXT,用来将 PCB排成队列。
优先数改变的原则:进程在就绪队列中呆一个时间片,优先数增加1。
进程每运行一个时间片,优先数减1。
二、实验感想:在第次试验时,老师建议大家应该开始自己写程序,可以借鉴参考网上的代码,但绝不能单单的COPY网上的程序了,吃饭容易种饭难哈,自己写动态高优先权调度要比从网上写个代码简单修改一下难得多呀。
我自己开始编时摸不着头脑,从哪里下手。
我还是从网上下了个代码,然后认真的独立几遍,主要理解弄明白她的编写思路,好让我有个清晰的思路!然后自己写程序,不过其中碰见的很多的问题。
动态优先权进程调度算法实验报告
《动态优先权进程调度算法》实验报告题目:动态优先权进程调度算法的模拟实现专业:班级:学号:姓名:日期:一﹑实验目的通过动态优先权算法的模拟加深对进程概念和进程调度过程的理解。
二﹑实验内容与基本要求编制模拟动态优先权算法的程序,并给出的例子验证所编写的程序的正确性。
(1)用C语言实现对N个进程采用动态优先权算法的调度。
(2)每个用来标识进程的进程控制块PCB可用结构来描述,包括以下字段:✧进程标识数ID。
✧进程优先数PRIORITY,并规定优先数越大的进程,其优先权越高。
✧进程已占用CPU时间CPUTIME。
✧进程还需占用的CPU时间ALLTIME。
当进程运行完毕时,ALLTIME变为0。
✧进程的阻塞时间STARTBLOCK,表示当进程再运行STARTBLOCK个时间片后,进程将进入阻塞状态。
✧进程被阻塞的时间BLOCKTIME,表示已阻塞的进程再等待BLOCKTIME个时间片后,将转换成就绪状态。
✧进程状态STATE。
✧队列指针NEXT,用来将PCB排成队列。
(3)优先数改变的原则:✧进程在就绪队列中呆一个时间片,优先数增加1。
✧进程每运行一个时间片,优先数减3。
(4)假设在调度前,系统中有5个进程,它们得初始状态如下:为了清楚地观察每个进程的调度过程,程序应将每个时间片内的进程的情况显示出来,包括正在运行的进程,处于就绪队列中的进程和处于阻塞队列中的进程。
格式如下:RUNNING PROG:iREADY_QUEUE:->id1->id2BLOCK_QUEUE:->id3->id4==========================================================ID 0 1 2 3 4PRIORITY P0 P1 P2 P3 P4CPUTIME C0 C1 C3 C4 C5ALLTIME A0 A1 A2 A3 A4STARTBLOCK T0 T1 T2 T3 T4BLOCKTIME B0 B1 B2 B3 B4STATE S0 S1 S2 S3 S4三、实验报告内容1、动态优先权算法原理动态优先权是指,在创建进程时所赋予的优先权,是可以随进程的推进或随其等待时间的增加而改变的,以便获得更好的调度性能。
动态优先权进程调度算法模拟实验报告
动态优先权进程调度算法模拟实验报告动态优先权调度算法是一种动态调度算法,根据进程的优先级来决定下一个要执行的进程。
进程的优先级可以根据其紧迫性、重要性和资源需求等因素来确定。
本实验利用模拟算法来模拟动态优先权调度算法,并通过实例来说明该调度算法的工作原理和优缺点。
一、实验目的通过本实验,我们可以了解动态优先权调度算法的工作原理,掌握如何使用模拟算法来模拟进程的调度过程,进一步了解该调度算法的优缺点。
二、实验环境本实验使用C++编程语言来实现动态优先权调度算法的模拟。
编译器使用Dev-C++。
三、实验步骤1.设计进程控制块(PCB)的数据结构,包括进程优先级、进程标识、进程状态等信息。
2.设计模拟算法来模拟动态优先权调度算法。
具体算法如下:a.初始化就绪队列,将所有的进程按照优先级插入到就绪队列中。
b.选择优先级最高的进程执行,并更新该进程的优先级。
c.执行完毕后更新进程的状态,并将其从就绪队列中删除。
d.如果新的进程到达,将其插入到就绪队列中。
3.实现主函数,模拟进程的创建、调度和执行过程。
4.进行多个实例的测试,观察进程的调度顺序和执行结果。
5.总结实验结果,分析动态优先权调度算法的优缺点。
四、实验结果与分析通过多个实例的测试,我们可以观察到动态优先权调度算法的工作过程和效果。
该算法可以根据进程的优先级来确定下一个要执行的进程,从而可以更好地满足不同进程的需求。
同时,动态优先权调度算法可以确保优先级高的进程能够及时得到执行,提高系统的响应速度。
然而,动态优先权调度算法存在一些缺点。
首先,该算法对进程的优先级要求较高,需要合理设置进程的优先级。
如果优先级设置不合理,可能导致优先级高的进程一直占用CPU资源,而优先级低的进程无法得到执行,造成资源浪费。
其次,该算法没有考虑进程的等待时间和执行时间,容易导致饥饿现象的发生,即一些进程无法得到执行。
五、实验总结通过本实验,我们了解了动态优先权调度算法的工作原理和模拟方法。
处理器调度之动态优先数调度算法
(3)处理器总是选择队首进程运行。釆用动态改变优先数的办法,进程每运
1
J
1——-——————
1— ——• —•——•——
|i->4
^process
Wi
1— — — — — — —•
Mi
卩
・\n,z, >pname);
1
实验内容及要求
实验内容:按优先数调度算法实现处理器调度。
实验要求:能接受键盘输入的进程数、进程标识、进程优先数及要求运行时 间,能显示每次进程调度的情况:运行进程、就绪进程和就绪进程的排列情况。
实验目的
本实验模拟在单处理器环境下的处理器调度,加深了解处理器调度工作。
实验环境
本实验的设计基于Windows7操作系统DevC+4-环境,用C语言实现编程。
{
strcpy (name, p->pname);
priorityNum=p->priority;
ti meNum=p->runT ime;
strcpy (p->pname, rear->pname);
p->priority=rear->priority; p->runTime=rear->runTime; strcpy (rear~>pname, name);
p=p->next;
}
}
void runProcess()
{
PCB *p=;
printf (,zprocess run:\n,z):
printf("%s\n", p->pname);
使用动态优先权的进程调度算法的模拟实验
使用动态优先权的进程调度算法的模拟实验进程调度算法是操作系统中对进程进行调度的一种策略,动态优先权调度算法是其中一种常用的调度算法。
下面将对动态优先权调度算法进行模拟实验,并对实验结果进行分析。
首先,我们定义进程的属性包括进程编号、到达时间、服务时间、优先权和完成时间等。
动态优先权调度算法的基本思想是根据进程的优先权决定下一个被调度的进程,优先权越高,被调度的机会越大。
实验过程如下:1.创建一个进程队列,用来存放待调度的进程。
2.输入进程的个数,并依次输入每个进程的到达时间、服务时间和优先权。
3.将所有进程按照到达时间进行排序。
4.从排好序的进程队列中选择优先权最高的进程,即优先权最大的进程。
5.通过执行该进程进行模拟,更新进程队列中的进程信息。
6.根据更新后的进程信息,重新选择下一个被调度的进程。
7.重复步骤5和6,直到所有进程执行完毕。
对于每个进程,我们可以记录其等待时间、周转时间和带权周转时间。
等待时间即为该进程在就绪队列中等待的时间,周转时间是指从进程提交到完成的时间,即完成时间减去到达时间,带权周转时间是指每个进程的周转时间除以服务时间,用来评估进程的调度效果。
下面是一个动态优先权调度算法的模拟实验示例:```pythonclass Process:self.id = idself.priority = prioritydef __lt__(self, other):return self.priority < other.prioritydef dynamic_priority_scheduling(processes):queue = []while processes or queue:for process in processes:queue.append(process)processes.remove(process)queue.sort(reverse=True) # 根据进程的优先权进行排序if queue:process = queue.pop(0)for p in queue:if __name__ == '__main__':n = int(input("Enter the number of processes: "))processes = []for i in range(n):priority = int(input("Enter priority for process {}:".format(i+1)))dynamic_priority_scheduling(processes)```以上代码定义了一个Process类来表示进程,并使用动态优先权调度算法对进程进行调度。
操作系统实验——动态优先级进程调度实验报告
1.实验名称:动态优先权调度过程中就绪队列的模拟2.实验要求:采用动态优先权的进程调度算法,用C语言编程模拟调度过程中每个时间片内的就绪队列。
3.实验内容:(1)每个进程控制块PCB用结构描述,包括以下字段:*进程标识符id*进程优先数priority,并规定优先数越大的进程,其优先权越高。
*进程已占用的CPU时间cputime*进程还需占用的CPU时间alltime,当进程运行完毕时,aiitime变为0*进程的阻塞时间startblock,当进程再运行startblock个时间片后,进程将进入阻塞状态*进程被阻塞的时间blocktime,已阻塞的进程再等待blocktime个时间片后,将转换成就绪状态*进程状态state*队列指针next,将PCB排成队列。
2)调度前,系统中有五个进程,它们的初始状态如下:3)进程在就绪队列呆一个时间片,优先数增加1。
4)进程每运行一个时间片,优先数减3。
5)按下面格式显示每个时间片内就绪队列的情况:READY_QUEUE:->id1->id24.任务分析进程控制块用结构体来表示,包含它的各项属性。
建立两个队列:一个就绪队列,一个阻塞队列。
创建一个进程控制块表示当前正在运行的进程。
程序开始运行时,所有进程都在就绪队列中。
当startblock减少到0时,进程进入阻塞队列。
在阻塞队列中的进程,当blocktime减少到0时,转入就绪队列。
在就绪队列中的进程,如果优先级比当前正在执行的进程高,就可以取代当前进程获取时间片。
当前进程如果运行完毕,就绪队列中优先级最高的进程就可以成为新当前进程。
5.程序流程图#include〈iostream〉#include〈string〉usingnamespace std;#define LEN5typedefenum STATE{READYBLOCKEND}STATE;//定义进程控制块typedefstruct PCB{int id;int priority;int cputime;int alltime;int startblock;int blocktime;STATE state;}PCB;//定义队列typedefstruct queue{int si ze;PCB*data[LEN];}Queue;PCB ps[LEN];PCB*cp; //进程最大数量//进程状态//就绪//阻塞//完成//进程标识符//进程优先级//已占用的CPU时间//还需占用的CPu时间//阻塞时间//被阻塞时间//进程状态//队列中进程的数量//进程的指针//进程数组//当前正在运行的进程6.程序清单Queue rQueue,bQueue;//就绪队列和阻塞队列//就绪队列按优先级降序排序(使用了冒泡排序法)void rQueueSort(){ PCB*temp;for(int i=0;i<rQueue.size-1;i++){for(int j=0;j<rQueue.size-1-i;j++){if(rQueue.data[j]-〉priority<rQueue.data[j+1]-〉priority){temp=rQueue.data[j];rQueue.data[j]=rQueue.data[j+1];}}rQueue.dataj+1]=temp;}}//初始化void init(){//给进程赋值for(int i=0;i<LEN;i++){ps[i].id=i;ps[i].state=READY;ps[i].cputime=0;ps[i].alltime=3;ps[i].blocktime=0;ps[i].startblock=T;}ps[0].priority=9;ps[1].priority=38;ps[2].priority=30;ps[3].priority=29;ps[4].priority=0;ps[2].alltime=6;ps[4].alltime=4;ps[0].startblock=2;ps[0].blocktime=3;cp=NULL;//当前进程赋空bQueue.size=0;//阻塞队列没有进程for(int i=0;i<LEN;i++){bQueue.data[i]=NULL;rQueue.data[i]=&ps[i];}rQueue.size=5;//所有进程全部进入就绪队列rQueueSort();//对就绪队列排序}//打印void print(){cout〈〈"\nRUNNINGPROG:";if(cp!=NULL){cout〈〈cp->id;}cout<<"\nREADY_QUEUE:";for(int i=0;i<rQueue.size;i++){cout〈〈"-〉"〈〈rQueue.data[i]-〉id; }cout<<"\nBLOCK_QUEUE:";for(int i=0;i<bQueue.size;i++){cout〈〈"-〉"〈〈bQueue.data[i]-〉id; }cout〈〈"\n"<<endl;cout<<"ID\t\t";for(int i=0;i<LEN;i++){cout〈〈ps[i].id<<"\t";}cout<<"\nPRI0RITY\t";for(int i=0;i<LEN;i++){cout〈〈ps[i].priority〈〈"\t";}cout<<"\nCPUTIME\t\t";for(int i=0;i<LEN;i++){cout〈〈ps[i].cputime〈〈"\t";}cout<<"\nALLTIME\t\t";for(int i=0;i<LEN;i++){cout〈〈ps[i].alltime〈〈"\t";}cout<<"\nSTARTBLOCK\t";for(int i=0;i<LEN;i++){cout〈〈ps[i].startblock<<"\t";}cout<<"\nBLOCKTIME\t";for(int i=0;i<LEN;i++){cout〈〈ps[i].blocktime<<"\t";}cout<<"\nSTATE\t\t";for(int i=0;i<LEN;i++){if(ps[i].state==READY){cout<<"READY"<<"\t";}elseif(ps[i].state==BLOCK){cout<<"BLOCK"<<"\t";}elseif(ps[i].state==END){cout〈〈"END"<<"\t";}}cout〈〈endl;}//出队,返回进程指针PCB*pop(Queue*q){PCB*temp;if(q-〉size>0){temp=q-〉data[0];//取出队首进程for(int i=0;i<q-〉size-1;i++){q-〉data[i]=q-〉data[i+1];//其他进程依次向前移动}q->size__;return temp;//返回队首进程}return NULL;}//入队void push(Queue*q,PCB*p){if(q_>size<LEN){q_>data[q_〉size]=p;//将入队的进程放在队尾q_>size++;}return;}//运行进程void run(){if(rQueue.size〉0||bQueue.size〉0){if(cp==NULL){//程序一开始运行时,从就绪队列取出首进程cp=pop(&rQueue);}//当前进程没有结束,但优先级比就绪队列首进程低if(cp_〉alltime〉0&&cp_>priority<rQueue.data[0]_〉priority){}push(&r Queue,c//改变进程状态//从就绪队列取出新的当前进程//修改当前进程的状态 //将当前进程加入阻塞队列 //从就绪队列取出新的当前进程{//当前进程的startblock 为正数时//运行一次减一个时间片//减到0时,修改进程状态//每运行一个时间片//就绪队列中的进程优先级+1//每运行一个时间片//阻塞队列中的进程blocktime-1//将当前进程放入就绪队列 //就绪队列队首进程成为当前进程if (cp-〉alltime==0){cp->state =END ;cp=pop(&rQueue); }//如果当前进程运行结束//startblock 为0,标志着当前进程要进入阻塞状态if (cp —>startblock==0&&cp —>blocktime>0){cp —>state=BLOCK ; push(&bQueue,cp); cp=pop(&rQueue); }elseif (cp —>startblock>0)cp —>st artblock 一; }cp —>alltime ——;if (cp —>alltime==0){cp —>state=END ;for (int i=0;i<rQueue.size;i++){rQueue.data[i]-〉priority++; }for (int i=0;i<bQueue.size;i++){if (bQueue.data[i]-〉blocktime>0){bQueue.data[i]-〉blocktime--; }//当阻塞队列队首进程blocktime 为0时if (bQueue.size 〉0&&bQueue.data[0]-〉blocktime==0){bQueue.data[0]-〉state=READY ;//修改进程状态push(&rQueue,pop(&bQueue));//将阻塞队列首进程取出,放入就绪队列cp —〉priority-=3;//修改当前进程的优先级cp —>cputime++; //当前进程占用CPU 时间片+1 if (cp —>alltime>0){//当前进程还需运行的时间片-1}//每运行一个时间片,就绪队列排一次序rQueueSort();} }//主函数int main(){init();//初始化 print();//打印进程信息 while (1){_sleep(1000);if (rQueue.size==0&&bQueue.size==0){//当两个队列都为空时,结束程序cp-〉state=END ;break ; }run();//运行进程 print();//打印进程信息 }return 0; }7.实验过程记录m 匚:\WINDQWS\system32\cmd.exe程序开始执行,当前进程是优先级最高的1号进程,1号进程的优先级减3、cputime++、执行几次之后,1号进程执行完毕而且优先级也不是最高的了,所以优先级为33的2号进程成为当前进程,开始执行。
实验二处理机调度
实验二动态高优先权优先调度实验内容:模拟实现动态高优先权优先(若数值越大优先权越高,每运行一个时间单位优先权-n,若数值越小优先权越高,没运行一个时间单位优先权+n),具体如下:设置作业体:作业名,作业的到达时间,服务时间,初始优先权,作业状态(W——等待,R ——运行,F——完成),作业间的链接指针作业初始化:由用户输入作业名、服务时间、初始优先权进行初始化,同时,初始化作业的状态为W。
显示函数:在作业调度前、调度中和调度后进行显示。
排序函数:对就绪状态的作业按照优先权排序。
优先权相同时进入等待队列时间早的作业在前。
注意考虑到达时间调度函数:每次从等待队列队首调度优先权最高的作业执行,状态变化。
并在执行一个时间单位后优先权变化,服务时间变化,状态变化。
当服务时间为0时,状态变为F。
删除函数:撤销状态为F的作业。
实验要求:1、测试数据可以随即输入或从文件中读入。
2、必须要考虑到作业的到达时间3、最终能够计算每一个作业的周转时间。
实验三时间片轮转调度算法模拟实现时间片轮转调度算法,具体如下:设置进程体:进程名,进程的到达时间,服务时间,,进程状态(W——等待,R——运行,F ——完成),进程间的链接指针进程初始化:由用户输入进程名、服务时间进行初始化,同时,初始化进程的状态为W。
显示函数:在进程调度前、调度中和调度后进行显示。
排序函数:对就绪状态的进程按照进入就绪队列的时间排序,新到达的进行应优先于刚刚执行过的进程进入就绪队列的队尾。
注意考虑到达时间调度函数:每次从就绪队列队首调度优一个进程执行,状态变化。
并在执行一个时间片后化,服务时间变化,状态变化。
当服务时间为0时,状态变为F。
删除函数:撤销状态为F的进行。
实验要求:1、测试数据可以随即输入或从文件中读入。
2、必须要考虑到进程的到达时间3、最终能够计算每一个进程的周转时间的带权周转时间。
动态优先权算法
华北科技学院计算机系综合性实验实验报告课程名称C操作系统实验学期至学年第学期学生所在系部计算机系年级专业班级学生姓名SORRY,枪走火学号任课教师实验成绩计算机系制《C操作系统》课程综合性实验报告开课实验室:基础六2011年5月20日实验题目进程调度算法设计一、实验目的通过对进程调度算法的模拟,进一步理解进程的基本概念,加深对进程运行状态和进程调度过程、调度算法的理解。
二、设备与环境1.硬件设备:PC机一台2.软件环境:安装Windows操作系统或者Linux操作系统,并安装相关的程序开发环境,如C \C++\Java等编程语言环境。
三、实验内容(1)用C/C++语言(或其它语言,如Java)实现对N个进程采用某种进程调度算法(如动态优先权优先)的调度。
(2)每个用来标识进程的进程控制块PCB可用结构来描述,包括以下字段:✧进程标识数ID。
✧进程优先数PRIORITY,并规定优先数越大的进程,其优先权越高。
✧进程还需占用CPU时间CPUTIME。
✧进程进入ready队列还需等待时间WAITT。
✧进程被阻塞时间BLOCKT。
✧进程周转时间ALLTIME。
✧进程状态标记STATE。
✧队列指针NEXT,用来将PCB排成队列。
(3)为了清楚地观察每个进程的调度过程,程序应将每个时间片内的进程的情况显示出来,包括正在运行的进程,处于就绪队列中的进程和处于阻塞队列中的进程。
(4)分析程序运行的结果,谈一下自己的认识。
四、实验结果及分析1.实验设计说明用C语言实现动态优先权优先进程调度算法设计。
第10页。
处理机调度算法实验报告
实验二处理机调度算法(1)处理机调度的目的是什么?为提高内存利用率和系统吞吐量。
将那些暂时不能运行的进程调至外存,当内存不紧张时,将那些具备运行条件的就绪进程重新调入内存。
合理快速的处理计算机软件硬件资源,分配处理机,用以提高处理机的利用率及改善系统性能(吞吐量,响应时间)。
(2)处理机调度的算法有哪些,各自的优缺点是什么?①先来先服务算法:有利于长作业(进程),不利于短作业(进程);②短作业优先调度算法:有利于短作业(短进程),不利于长作业(长进程);③高优先权调度算法:静态缺点:可能导致低优先权进程长期得不到调度甚至饿死;动态:优先权随进程等待时间增加或执行而变④高响应比优先调度算法⑤基于时间片轮转调度算法:时间片太小,会频繁发生中断,系统开销增大时间片太大,响应进程慢。
⑥多级反馈队列调度算法:具有较好的性能,能很好满足各类型用户的需求。
1.内存中作业运行的序列:A、B、D、C2.A进入内存的时刻1,结束的时刻5B进入内存的时刻5,结束的时刻8D进入内存的时刻8,结束的时刻10C进入内存的时刻10,结束的时刻153.平均周转时间:61.内存中作业运行的序列:B、C、A、D2.B进入内存的时刻3,结束的时刻6C进入内存的时刻6,结束的时刻11A进入内存的时刻11,结束的时刻15D进入内存的时刻15,结束的时刻173.平均周转时间:8.75(4)画出处理机调度算法的程序流程图;(5)补全参考程序;void process(int currentTmp, int nextTmp){int j;int s=nextTmp-currentTmp;while(memoryNum>0 && s>=memory[0].needtime){totalTime=totalTime+memory[0].needtime;s=s-memory[0].needtime;printf("线程%c的开始时间是:%d,结束时间是:%f\n",memory[0].id,memory[0].cputime,totalTime+1);allTime+=totalTime+1;memoryNum--;for(j = 1; j<=memoryNum; j++)memory[j-1] = memory[j];if(waitNum>0 && s>0){memory[memoryNum] = wait[0];memoryNum++;waitNum--;for(j = 1; j<=waitNum; j++)wait[j-1] = wait[j];sort(memory,memoryNum, 'P');}}if(memoryNum>0 && s<memory[0].needtime){totalTime=totalTime+s;memory[0].needtime-=s;}}//选择排序算法,若key为'P'则按优先级大的排在数组首,否则为'N'则按所需时间进行短作业优先排序void sort(PCB *pcb,int count, char key){PCB *p;PCB mao;int i,j;if(key=='P'){for(i=0;i<count;i++){p=pcb;for(j=0;j<count-1-i;j++){if((p->priority)>((p+1)->priority)){mao=*p;*p=*(p+1);*(p+1)=mao;}p++;}}}else if(key=='N'){for(i=0;i<count;i++){p=pcb;for(j=0;j<count-1-i;j++){if((p->needtime)>((p+1)->needtime)){mao=*p;*p=*(p+1);*(p+1)=mao;}p++;}}}}(6)基于例题中的例子,分别运行两种处理机调度算法并将运行结果截图。
使用动态优先权的进程调度算法的模拟
3实验结果
(1)流程图
操作系统实验报告
%操作系统实验报告
(2)程序源代码
include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct node
{
int id;〃进程标识数
int priority;〃进程优先数,优先数越大优先级越高
(
int i;//i为循环计数器
PCB *head, *templ, *temp2, *temp3;//head为就绪队列的头指针,tempi为创建进程结点的指针,
temp2、temp3分别为比较结点的前驱结点和比较结点for(i=0; i<num; i++)〃根据进程的个数创建结点并按从大到小的顺序进行排序
if(i==0)〃如果创建的是第一个结点
{
head=templ;
head->next=NULL;
continue;
}
if(head->priority < templ->priority)〃如果创建结点中所保存的数比头结点所保存的数要大,则直
接把该结点插入到头结点之前
(
templ->next=head; head=templ;
te m p=temp->next;
)
while(alltime > 0)
(
if(head!=NULL)
{
run=head;〃把就绪队列中的第一个进程取出来执行
head=head->next;〃就绪队列的头指针指向下一个结点
高优先权优先的进程调度算法模拟
高优先权优先的进程调度算法模拟进程调度算法是操作系统中的一个重要组成部分,其中高(动态)优先权优先调度算法是一种常用的调度算法。
本文将通过模拟该算法的工作原理、实现过程和应用场景等方面,详细介绍高(动态)优先权优先进程调度算法。
一、高(动态)优先权优先进程调度算法的原理及特点:1.原理:高(动态)优先权优先进程调度算法根据进程的优先权值来确定进程执行的顺序,优先权值高的进程先执行。
在这种算法中,每个进程都有一个优先权值,优先权值越大,进程执行的优先级也越高。
2.特点:(1)动态性:高(动态)优先权优先进程调度算法中,进程的优先权值可以根据进程的状态和需求进行动态调整。
例如,用户交互进程或实时进程的优先权值可以较高,而后台进程的优先权值可以较低。
(2)公平性:高(动态)优先权优先进程调度算法能够保证每个进程都有执行的机会,不会出现饥饿现象。
(3)无法避免的问题:由于优先权值的动态调整,高(动态)优先权优先进程调度算法可能导致一些进程饥饿或低优先级进程无法得到执行的情况。
二、高(动态)优先权优先进程调度算法的实现过程:1.初始化:设定每个进程的优先权值,创建就绪队列和堆栈等数据结构,初始化进程的状态和资源。
2. 进程调度:根据进程的优先权值,从就绪队列中选择优先权值最高的进程进行执行。
如果存在多个优先权值相同的进程,可以使用先到先服务(FIFO)或轮转(Round-robin)等调度策略来决定执行顺序。
3.执行进程:将选中的进程从就绪队列中移除,并切换到该进程的上下文,开始执行进程的指令。
4.中断处理或进程阻塞:在进程执行过程中,如果发生中断事件(如I/O请求、信号响应等),则暂停当前进程的执行,并将其状态置为阻塞态,将进程放入阻塞队列中等待事件完成或唤醒信号。
5.进程唤醒或时间片过期:当进程阻塞的事件完成或等待一段时间后,重新将该进程放入就绪队列中,更新其优先权值。
6.进程终止或等待:当进程执行完所有指令或主动请求等待时,将进程从系统中移除,并释放其占用的资源。
操作系统实验——动态优先级进程调度实验报告
1. 实验名称:动态优先权调度过程中就绪队列的模拟2. 实验要求:采用动态优先权的进程调度算法,用C语言编程模拟调度过程中每个时间片内的就绪队列。
3. 实验内容:(1)每个进程控制块PCB用结构描述,包括以下字段:*进程标识符id*进程优先数priority,并规定优先数越大的进程,其优先权越高。
*进程已占用的CPU时间cputime*进程还需占用的CPU时间alltime,当进程运行完毕时,aiitime变为0*进程的阻塞时间startblock,当进程再运行startblock个时间片后,进程将进入阻塞状态*进程被阻塞的时间blocktime,已阻塞的进程再等待blocktime 个时间片后,将转换成就绪状态*进程状态state*队列指针next,将PCB排成队列。
(2)调度前,系统中有五个进程,它们的初始状态如下:(3)进程在就绪队列呆一个时间片,优先数增加1。
(4)进程每运行一个时间片,优先数减3。
(5)按下面格式显示每个时间片内就绪队列的情况:READY_QUEUE :->id1->id24. 任务分析进程控制块用结构体来表示,包含它的各项属性。
建立两个队列:一个就绪队列,一个阻塞队列。
创建一个进程控制块表示当前正在运行的进程。
程序开始运行时,所有进程都在就绪队列中。
当startblock减少到0时,进程进入阻塞队列。
在阻塞队列中的进程,当blocktime减少到0时,转入就绪队列。
在就绪队列中的进程,如果优先级比当前正在执行的进程高,就可以取代当前进程获取时间片。
当前进程如果运行完毕,就绪队列中优先级最高的进程就可以成为新当前进程。
5. 程序流程图6. 程序清单#include<iostream>#include<string>using namespace std;#define LEN 5 // 进程最大数量typedef enum STATE// 进程状态{READY, // 就绪BLOCK, // 阻塞END// 完成}STATE;// 定义进程控制块typedef struct PCB {int id; // 进程标识符int priority; // 进程优先级int cputime; // 已占用的CPU时间int alltime; // 还需占用的CPU时间int startblock; // 阻塞时间int blocktime; // 被阻塞时间STATE state; // 进程状态}PCB;// 定义队列typedef struct queue {int size; // 队列中进程的数量PCB *data[LEN]; // 进程的指针}Queue;PCB ps[LEN]; // 进程数组PCB *cp; // 当前正在运行的进程Queue rQueue, bQueue; // 就绪队列和阻塞队列// 就绪队列按优先级降序排序(使用了冒泡排序法)void rQueueSort() {PCB *temp;for (int i = 0; i < rQueue.size - 1; i++) {for (int j = 0; j < rQueue.size - 1 - i; j++) {if (rQueue.data[j]->priority < rQueue.data[j + 1]->priority) { temp = rQueue.data[j];rQueue.data[j] = rQueue.data[j + 1];rQueue.data[j + 1] = temp;}}}}// 初始化void init() {// 给进程赋值for (int i = 0; i < LEN; i++) {ps[i].id = i;ps[i].state = READY;ps[i].cputime = 0;ps[i].alltime = 3;ps[i].blocktime = 0;ps[i].startblock = -1;}ps[0].priority = 9;ps[1].priority = 38;ps[2].priority = 30;ps[3].priority = 29;ps[4].priority = 0;ps[2].alltime = 6;ps[4].alltime = 4;ps[0].startblock = 2;ps[0].blocktime = 3;cp = NULL; // 当前进程赋空bQueue.size = 0; // 阻塞队列没有进程for (int i = 0; i < LEN; i++) {bQueue.data[i] = NULL;rQueue.data[i] = &ps[i];}rQueue.size = 5; // 所有进程全部进入就绪队列rQueueSort(); // 对就绪队列排序}// 打印void print() {cout <<"\nRUNNING PROG: ";if (cp != NULL) {cout<< cp->id;}cout <<"\nREADY_QUEUE:";for (int i = 0; i < rQueue.size; i++) {cout<<"->"<< rQueue.data[i]->id;}cout <<"\nBLOCK_QUEUE:";for (int i = 0; i < bQueue.size; i++) {cout <<"->"<< bQueue.data[i]->id;}cout <<"\n-------------------------------------------------------"<< endl;cout <<"ID\t\t";for (int i = 0; i < LEN; i++) {cout << ps[i].id <<"\t";}cout <<"\nPRIORITY\t";for (int i = 0; i < LEN; i++) {cout << ps[i].priority <<"\t";}cout <<"\nCPUTIME\t\t";for (int i = 0; i < LEN; i++) {cout << ps[i].cputime <<"\t";}cout <<"\nALLTIME\t\t";for (int i = 0; i < LEN; i++) {cout << ps[i].alltime <<"\t";}cout <<"\nSTARTBLOCK\t";for (int i = 0; i < LEN; i++) {cout << ps[i].startblock <<"\t";}cout <<"\nBLOCKTIME\t";for (int i = 0; i < LEN; i++) {cout << ps[i].blocktime <<"\t";}cout <<"\nSTATE\t\t";for (int i = 0; i < LEN; i++) {if (ps[i].state == READY) {cout <<"READY"<<"\t";}else if (ps[i].state == BLOCK) {cout <<"BLOCK"<<"\t";}else if (ps[i].state == END) {cout <<"END"<<"\t";}}cout << endl;}// 出队,返回进程指针PCB* pop(Queue *q) {PCB *temp;if (q->size > 0) {temp = q->data[0]; // 取出队首进程for (int i = 0; i < q->size - 1; i++) {q->data[i] = q->data[i + 1]; // 其他进程依次向前移动}q->size--;return temp; // 返回队首进程}return NULL;}// 入队void push(Queue *q, PCB *p) {if (q->size < LEN) {q->data[q->size] = p; // 将入队的进程放在队尾q->size++;}return;}// 运行进程void run() {if (rQueue.size > 0 || bQueue.size > 0) {if (cp == NULL) { // 程序一开始运行时,从就绪队列取出首进程cp = pop(&rQueue);}// 当前进程没有结束,但优先级比就绪队列首进程低if (cp->alltime > 0 && cp->priority < rQueue.data[0]->priority) {push(&rQueue, cp); // 将当前进程放入就绪队列cp = pop(&rQueue); // 就绪队列队首进程成为当前进程}if (cp->alltime == 0) { // 如果当前进程运行结束cp->state = END; // 改变进程状态cp = pop(&rQueue); // 从就绪队列取出新的当前进程}cp->priority -= 3; // 修改当前进程的优先级// startblock为0,标志着当前进程要进入阻塞状态if (cp->startblock == 0 && cp->blocktime > 0) {cp->state = BLOCK; // 修改当前进程的状态push(&bQueue, cp); // 将当前进程加入阻塞队列cp = pop(&rQueue); // 从就绪队列取出新的当前进程}else if (cp->startblock > 0) { // 当前进程的startblock为正数时cp->startblock--; // 运行一次减一个时间片}cp->cputime++; // 当前进程占用CPU时间片+1if(cp->alltime > 0){ // 当前进程还需运行的时间片-1cp->alltime--;if (cp->alltime == 0) { // 减到0时,修改进程状态cp->state = END;}}for (int i = 0; i < rQueue.size; i++) { // 每运行一个时间片rQueue.data[i]->priority++; // 就绪队列中的进程优先级+1 }for (int i = 0; i < bQueue.size; i++) { // 每运行一个时间片if (bQueue.data[i]->blocktime > 0) { // 阻塞队列中的进程blocktime-1 bQueue.data[i]->blocktime--;}}// 当阻塞队列队首进程blocktime为0时if (bQueue.size > 0 && bQueue.data[0]->blocktime == 0) {bQueue.data[0]->state = READY; // 修改进程状态push(&rQueue, pop(&bQueue)); // 将阻塞队列首进程取出,放入就绪队列}// 每运行一个时间片,就绪队列排一次序rQueueSort();}}// 主函数int main() {init(); // 初始化print(); // 打印进程信息while (1) {_sleep(1000);if (rQueue.size == 0 && bQueue.size == 0) { // 当两个队列都为空时,结束程序cp->state = END;break;}run(); // 运行进程print(); // 打印进程信息}return 0;}7. 实验过程记录程序开始执行,当前进程是优先级最高的1号进程,1号进程的优先级减3、cputime++、alltime--。
处理器调度之动态优先数调度算法
处理器调度之动态优先数调度算法动态优先数调度算法是一种常用的处理器调度算法,它根据进程的优先级来动态地分配处理器时间。
本文将介绍动态优先数调度算法的基本原理、优缺点以及应用场景。
动态优先数调度算法根据每个进程的实时状态来动态地调整它们的优先级。
进程的优先级可以根据一定的规则进行调整,通常根据进程等待时间、进程运行时间、进程优先级本身等因素来进行计算。
优先数越高的进程将被优先调度执行,从而提高系统的响应速度和效率。
动态优先数调度算法的基本原理是,在每次调度时,系统会根据当前进程的运行情况和其他进程的状态来重新计算进程的优先级,并将优先级最高的进程调度至处理器执行。
这样可以确保当前最需要处理器执行的进程得到优先处理,从而提高系统的整体性能。
动态优先数调度算法的优点之一是能够根据实时情况进行动态调整。
它可以根据当前系统的负载情况和各个进程的状态来重新计算优先级,从而适应动态变化的环境。
这种自适应性能够确保系统能够根据实际需求进行合理的分配,提高系统的效率和响应速度。
另一个优点是动态优先数调度算法可以根据进程的优先级来进行资源分配。
优先数高的进程将得到更多的处理器时间,从而能够更快地执行完任务,并释放出资源。
这样可以提高系统的资源利用率,确保进程能够得到合理的执行。
然而,动态优先数调度算法也存在一些缺点。
首先,它需要对每个进程进行动态调整和计算优先级,这会增加系统的开销。
特别是当系统中存在大量进程时,计算优先级的时间开销将会变得非常大,从而降低系统的整体性能。
其次,动态优先数调度算法可能会导致一些进程的饥饿现象。
如果一些进程的优先级始终较低,那么它可能永远无法得到处理器的执行时间,从而一直处于等待状态。
动态优先数调度算法可以应用于各种操作系统和应用场景。
例如,在实时操作系统中,动态优先数调度算法可以根据任务的紧急程度和重要性进行进程调度,以确保实时任务能够得到及时响应。
在科学计算领域,动态优先数调度算法可以根据计算任务的复杂度和计算资源的可用性来调度任务,以提高计算效率。
高优先权优先调度算法
动态高优先权算法实验报告一、实验目的通过动态优先权算法的模拟加深对进程概念和进程调度过程的理解。
提高自己的动手能力,主要是通过自己去思考并自己编码更进一步及更贴切的去理解弄明白动态优先权算法的模拟加深对进程概念和进程调度过程的工作流程及其原理!二、实验要求1.在运行界面里输入进程名称,进程优先级和进程时间;2.每运行一个时间单位,作业的优先权级数减一;3.在运行出的用户界面中显示初始作业名,作业状态,优先权级数,需要服务的时间,已经运行的时间;4.每次调度前后显示作业队列;三、实验内容动态优先权是指在创建进程时所赋予的优先权,是可以随着进程的推进或随其等待时间得增加而改变的。
实验内容利用C语言来实现对N个进程采用动态优先权优先算法的进程调度。
优先数改变的原则:进程每运行一个时间片,优先数减1。
四、实验结果登陆界面:图1 图2输入进程名字,进程优先数和进程时间:图3图4图5 图6图7 图8五、实验小结本次实验代码和基于时间片轮转算法代码是一样的,是在别人代码的基础上,结合自己对高优先权算法和时间片轮转算法的了解,通过switch语句把两者合二为一了,当输入1的时候,执行HighPriority函数,也就是动态高优先权函数。
在实现的过程中,使用for语句,限制进程数为5个:for (int i = 0; i != 5; ++i),,定义pt作为临时节点来创建链表,processes作为头结点来存储链表,psorted用来存放排序后的链表。
这次实验,在最初的时候,遇到了很大的麻烦,毕竟是改的别人代码,所以对代码理解的不是很透彻,但在同学们和老师的帮助下,终于调试成功了。
也使我更加明白了高优先权调度的过程。
六、附录#include <stdio.h>#include <stdlib.h>struct PCB{char p_name[20];int p_priority;int p_needTime;int p_runTime;char p_state;struct PCB* next;};void HighPriority();void RoundRobin();void Information();char Choice();struct PCB* SortList(PCB* HL);int main(){Information();char choice = Choice();switch(choice){case '1':system("cls");HighPriority();break;case '2':system("cls");RoundRobin();break;default:break;}system("pause");return 0;}void Information(){printf("\n\n");printf(" ********************************************* \n");printf(" 模拟进程调度算法\n");printf(" ********************************************* \n\n\n");printf(" 班级:软件测试10-02班\n");printf(" 姓名:林文\n");printf(" 学号:541013110224\n");printf(" 实验日期:2013年04月9日\n\n\n\n\n\n");printf(" 按回车键进入演示程序");getchar();system("cls");}char Choice(){printf("\n\n");printf(" ********************************************* \n");printf(" 进程调度演示\n");printf(" *********************************************\n\n\n");printf(" 1.演示最高优先数优先算法。
处理器调度之动态优先数调度算法
1 处理机调度1.1 实验内容及要求实验内容:按优先数调度算法实现处理器调度。
实验要求:能接受键盘输入的进程数、进程标识、进程优先数及要求运行时间,能显示每次进程调度的情况:运行进程、就绪进程和就绪进程的排列情况。
1.2 实验目的本实验模拟在单处理器环境下的处理器调度,加深了解处理器调度工作。
1.3 实验环境本实验的设计基于Windows7操作系统DevC++5.11环境,用C语言实现编程。
1.4 实验思路(1) 每个进程用一个PCB来代表。
PCB的结构为:进程名——作为进程标识。
优先数——赋予进程的优先数,调度时总是选取优先数大的进程先执行。
要求运行时间——假设进程需要运行的单位时间数。
状态——假设两种状态:就绪和结束,用R表示就绪,用E表示结束。
初始状态都为就绪状态。
指针——按优先数的大小把5个进程连成队列,用指针指出下一个进程PCB的首地址。
(2) 开始运行之前,为每个进程确定它的“优先数”和“要求运行时间”。
通过键盘输入这些参数。
(3) 处理器总是选择队首进程运行。
采用动态改变优先数的办法,进程每运行1次,优先数减1,要求运行时间减1。
(4) 进程运行一次后,若要求运行时间不等于0,则将它加入就绪队列,否则,将状态改为“结束”,退出就绪队列。
(5) 若就绪队列为空,结束,否则转到(3)重复。
1.5 数据结构与全局变量typedef struct pcb{int pname;//进程名int priority;//优先级int runTime;//所需时间int state;//状态struct pcb* next;//下一个进程控制块}PCB; //进程控制块int num;//存储进程数PCB readyHead;//头结点,不存储进程PCB *readyEnd;//指向尾结点的指针1.6 函数说明(1)主函数main()输入进程数并调createProcess()初始化进程;若有进程,则依次调用sortProcess()、runProcess()、printProcessLink()和printProcessInfo()。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
《操作系统》课程实验报告实验名称:动态分区存储管理姓名:王子瑜学号: 541413450235地点:四教楼指导老师:刘放美专业班级:软件工程(测试技术14-02)实验成绩:一、实验要求:熟悉并掌握动态分区分配的各种算法。
熟悉并掌握动态分区中分区回收的各种情况,并能够实现分区合并。
二、实验内容:用高级语言模拟实现动态分区存储管理,要求:1、分区分配算法至少实现首次适应算法、最佳适应算法和最坏适应算法中的至少一种。
熟悉并掌握各种算法的空闲区组织方式。
2、分区的初始化——可以由用户输入初始分区的大小。
(初始化后只有一个空闲分区,起始地址为0,大小是用户输入的大小)3、分区的动态分配过程:由用户输入作业号和作业的大小,实现分区过程。
4、分区的回收:用户输入作业号,实现分区回收,同时,分区的合并要体现出来。
(注意:不存在的作业号要给出错误提示!)5、分区的显示:任何时刻,可以查看当前内存的情况(起始地址是什么,大小多大的分区时空闲的,或者占用的,能够显示出来)要求考虑:(1)内存空间不足的情况,要有相应的显示;(2)作业不能同名,但是删除后可以再用这个名字;(3)作业空间回收是输入作业名,回收相应的空间,如果这个作业名不存在,也要有相应的提示。
三、实验代码#include<stdio.h>#include<stdlib.h>#define SIZE 640 // 内存初始大小#define MINSIZE 5 // 碎片最小值enum STATE { Free, Busy };struct subAreaNode {int addr; // 起始地址int size; // 分区大小int taskId; // 作业号STATE state; // 分区状态subAreaNode *pre; // 分区前向指针subAreaNode *nxt; // 分区后向指针}subHead;// 初始化空闲分区链void intSubArea(){// 分配初始分区内存subAreaNode *fir = (subAreaNode *)malloc(sizeof(subAreaNode)); // 给首个分区赋值fir->addr = 0;fir->size = SIZE;fir->state = Free;fir->taskId = -1;fir->pre = &subHead;fir->nxt = NULL;// 初始化分区头部信息subHead.pre = NULL;subHead.nxt = fir;// 首次适应算法int firstFit(int taskId, int size){subAreaNode *p = subHead.nxt;while(p != NULL){if(p->state == Free && p->size >= size) {// 找到要分配的空闲分区if(p->size - size <= MINSIZE) {// 整块分配p->state = Busy;p->taskId = taskId;} else {// 分配大小为size的区间subAreaNode *node = (subAreaNode *)malloc(sizeof(subAreaNode)); node->addr = p->addr + size;node->size = p->size - size;node->state = Free;node->taskId = -1;// 修改分区链节点指针node->pre = p;node->nxt = p->nxt;if(p->nxt != NULL) {p->nxt->pre = node;}p->nxt = node;// 分配空闲区间p->size = size;p->state = Busy;p->taskId = taskId;}printf("内存分配成功!\n");return 1;}p = p->nxt;}printf("找不到合适的内存分区,分配失败...\n"); return 0;}// 最佳适应算法int bestFit(int taskId, int size){subAreaNode *tar = NULL;int tarSize = SIZE + 1;subAreaNode *p = subHead.nxt;while(p != NULL){// 寻找最佳空闲区间if(p->state == Free && p->size >= size && p->size < tarSize) { tar = p;tarSize = p->size;}p = p->nxt;}if(tar != NULL) {// 找到要分配的空闲分区if(tar->size - size <= MINSIZE) {// 整块分配tar->state = Busy;tar->taskId = taskId;} else {// 分配大小为size的区间subAreaNode *node = (subAreaNode *)malloc(sizeof(subAreaNode)); node->addr = tar->addr + size;node->size = tar->size - size;node->state = Free;node->taskId = -1;// 修改分区链节点指针node->pre = tar;node->nxt = tar->nxt;if(tar->nxt != NULL) {tar->nxt->pre = node;}tar->nxt = node;// 分配空闲区间tar->size = size;tar->state = Busy;tar->taskId = taskId;}printf("内存分配成功!\n");return 1;} else {// 找不到合适的空闲分区printf("找不到合适的内存分区,分配失败...\n");return 0;}}// 回收内存int freeSubArea(int taskId){int flag = 0;subAreaNode *p = subHead.nxt, *pp;while(p != NULL){if(p->state == Busy && p->taskId == taskId) {flag = 1;if((p->pre != &subHead && p->pre->state == Free) && (p->nxt != NULL && p->nxt->state == Free)) { // 情况1:合并上下两个分区// 先合并上区间pp = p;p = p->pre;p->size += pp->size;p->nxt = pp->nxt;pp->nxt->pre = p;free(pp);// 后合并下区间pp = p->nxt;p->size += pp->size;p->nxt = pp->nxt;if(pp->nxt != NULL) {pp->nxt->pre = p;}free(pp);} else if((p->pre == &subHead || p->pre->state == Busy) && (p->nxt != NULL && p->nxt->state == Free)) {// 情况2:只合并下面的分区pp = p->nxt;p->size += pp->size;p->state = Free;p->taskId = -1;p->nxt = pp->nxt;if(pp->nxt != NULL) {pp->nxt->pre = p;}free(pp);} else if((p->pre != &subHead && p->pre->state == Free)&& (p->nxt == NULL || p->nxt->state == Busy)) { // 情况3:只合并上面的分区pp = p;p = p->pre;p->size += pp->size;p->nxt = pp->nxt;if(pp->nxt != NULL) {pp->nxt->pre = p;}free(pp);} else {// 情况4:上下分区均不用合并p->state = Free;p->taskId = -1;}}p = p->nxt;}if(flag == 1) {// 回收成功printf("内存分区回收成功...\n");return 1;} else {// 找不到目标作业,回收失败printf("找不到目标作业,内存分区回收失败...\n");return 0;}}// 显示空闲分区链情况void showSubArea(){printf("*********************************************\n");printf("** 当前的内存分配情况如下: **\n");printf("*********************************************\n");printf("** 起始地址 | 空间大小 | 工作状态 | 作业号 **\n");subAreaNode *p = subHead.nxt;while(p != NULL){printf("**-----------------------------------------**\n"); printf("**");printf("%d k |", p->addr);printf("%d k |", p->size);printf(" %s |", p->state == Free ? "Free" : "Busy"); if(p->taskId > 0) {printf("%d ", p->taskId);} else {printf(" ");}printf("**\n");p = p->nxt;}printf("*********************************************\n"); }int main(){int option, ope, taskId, size;// 初始化空闲分区链intSubArea();// 选择分配算法while(1){printf("请选择要模拟的分配算法:0 表示首次适应算法,1 表示最佳适应算法\n");scanf("%d", &option);if(option == 0) {printf("你选择了首次适应算法,下面进行算法的模拟\n"); break;} else if(option == 1) {printf("你选择了最佳适应算法,下面进行算法的模拟\n"); break;} else {printf("错误:请输入 0/1\n\n");}}// 模拟动态分区分配算法while(1){printf("\n");printf("*********************************************\n"); printf("** 1: 分配内存 2: 回收内存 0: 退出 **\n"); printf("*********************************************\n"); scanf("%d", &ope);if(ope == 0) break;if(ope == 1) {// 模拟分配内存printf("请输入作业号: ");scanf("%d", &taskId);printf("请输入需要分配的内存大小(KB): ");scanf("%d", &size);if(size <= 0) {printf("错误:分配内存大小必须为正值\n"); continue;}// 调用分配算法if(option == 0) {firstFit(taskId, size);} else {bestFit(taskId, size);}// 显示空闲分区链情况showSubArea();} else if(ope == 2) {// 模拟回收内存printf("请输入要回收的作业号: ");scanf("%d", &taskId);freeSubArea(taskId);// 显示空闲分区链情况showSubArea();} else {printf("错误:请输入 0/1/2\n"); }}printf("分配算法模拟结束\n");return 0;}运行结果:五、实验总结注意:1.标题格式黑体4号加粗,正文宋体小四2.实验结果给出你程序运行时的截图3.实验总结是通过这次实验你学到的及不足的等方面的内容。