动态优先权调度算法的模拟

动态优先权调度算法的模拟

动态优先权调度算法的模拟

实验要求:用C语言编程实现动态优先权进程调度过程的模拟。
实验内容:
(1)每个进程控制块PCB用结构描述,包括以下字段:
*进程标识符id
*进程优先数priority,并规定优先数越大的进程,其优先权越高。
*进程已占用的CPU时间cputime
*进程还需占用的CPU时间alltime,当进程运行完毕时,aiitime变为0
*进程的阻塞时间startblock,当进程再运行startblock个时间片后,进程将进入阻塞状态
*进程被阻塞的时间blocktime,已阻塞的进程再等待blocktime 个时间片后,将转换成就绪状态
*进程状态state
*队列指针next,将PCB排成队列。

(2)调度前,系统中有五个进程,它们的初始状态如下:
ID 0 1 2 3 4
PRIORITY 9 38 30 29 0
CPUTIME 0 0 0 0 0
ALLTIME 3 3 6 3 4
STARTBLOCK 2 -1 -1 -1 -1
BLOCKTIME 3 0 0 0 0
STATE READY READY READY READY READY

(3)进程在就绪队列呆一个时间片,优先数增加1。
(4)进程每运行一个时间片,优先数减3。

编写程序按下面格式显示每个时间片内进程的情况:
RUNNING PROG:i
READY_QUEUE :->id1->id2
BLOCK_QUEUE :->id3->id4

ID 0 1 2 3 4
PRIORITY P0 P1 P2 P3 P4
CPUTIME C0 C1 C2 C3 C4
ALLTIME A0 A1 A2 A3 A4
STARTBLOCK T0 T1 T2 T3 T4
BLOCKTIME B0 B1 B2 B3 B4
STATE S0 S1 S2 S3 S4

任务分析

1.网上已经有了好多此方面的代码,自己只是一个小白,思路也是按着网上找来的自己写的。但是注释足够多。结果也是按着要求来输出的。希望能帮到大家。
2.网上大多用了一个cpuBusy的变量,用来判断是否cpu内有正在执行的进程,为了给大家展示进程间的切换要考虑的东西,所以就把那一变量给舍去了,但用那变量真的能节省好多代码量。
3.此个实验共有两种结果。一种是时间片执行完后显示的各进程信息,结果为19个时间片;另一种是时间片执行前各进程信息(也就是把初始化信息多输出一遍),结果为20个时间片。

代码如下

#include  《iostream》(此处尖括号应为英文状况)
using namespace std;
#define RUNNED -1
#define BLOCK 0
#define READY 1
#define RUN 2

struct PCB{
	int id;				//进程标识符
	int priority;		//优先权
	int cpuTime;		//已占用的CPU时间
	int allTime;		//还需占用的CPU时间
	int startBlock;		//进程再运行startBlock时间片后,进入阻塞状态
	int blockTime;		//进程被阻塞时间
	int state;			//进程状态,0--BLOCK,1--READY,-1--RUNNED,2--RUN
	PCB *next;			//下一进程指针

	PCB(int id,int priority,int cpuTime,int allTime,
		int startBlock,int blockTime,int state){		//结构体构造函数
		this->id=id;	
		this->priority=priority;	
		this->cpuTime=cpuTime;
		this->allTime=allTime;	
		this->startBlock=startBlock;
		this->blockTime=blockTime;	
		this->state=state;	
		this->next=NULL;
	}

};

int n;							//进程数
int timeSlice=0;				//时间片
PCB* ready_Queue_Head=NULL;		//就绪队列头指针
PCB* block_Queue_Head=NULL;		//阻塞队列头指针
PCB* running_proc=NULL;			//当前执行的进程,-1表示当前没有执行的进程
PCB* runned_proc=NULL;
PCB** processInfo=NULL;			//按id号升序把各进程存储



//初始化就绪、阻塞队列,各队列均有头结点
void InitQueue(){
	ready_Queue_Head=(PCB*)malloc(sizeof(PCB));	//为头指针分配空间
	ready_Queue_Head->next=NULL;		

	block_Queue_Head=(PCB*)malloc(sizeof(PCB));
	block_Queue_Head->next=NULL;
	
	runned_proc=(PCB*)malloc(sizeof(PCB));
	runned_proc->next=NULL;
}


//将进程插入相应队列,按优先权降序排列
void InsertProcess(PCB* process,PCB* Queue_head){
	PCB* p=Queue_head->next;	//指向第一条进程
	PCB* p_before=Queue_head;	//方便插入操作

	while(p!=NULL && process->priority<p->priority){	//按优先权降序排列
		p_before=p;
		p=p->next;
	}

	process->next=p;
	p_before->next=process;
}


//手动输入创建各进程
void CreateProcess(){
	cout<<"输入进程数:";
	cin>>n;
	processInfo=(PCB**)malloc(sizeof(PCB)*n);
	
	cout<<"输入进程的初始状态"<<endl;
	cout<<"Priority CPUTime AllTime StartBlock BlockTime State"<<endl;
	for(int i=0;i<n;i++){
		PCB *p=(PCB*)malloc(sizeof(PCB));
		cin>>p->priority>>p->cpuTime>>p->allTime>>p->startBlock
			>>p->blockTime>>p->state;
		p->id=i;
		InsertProcess(p,ready_Queue_Head);
		processInfo[i]=p;
	}
	cout<<"-----------------------------------------------------------------"<<endl;
}


//显示各队列和进程信息
void ShowQueue(){
	PCB* p=NULL;
	char* info[]={"ID","PRIORITY","CPUTIME","ALLTIME","STARTBLOCK","BLOCKTIME","STATE"};

	//运行中队列,-1表示没有执行中队列
	cout<<"RUNNING PROG:"<<(running_proc==NULL?-1:running_proc->id)<<endl;

	//就绪队列
	cout<<"READY_QUEUE :";
	for(p=ready_Queue_Head->next;p!=NULL;p=p->next){
		cout<<"->"<<p->id;
	}
	cout<<endl;

	//阻塞队列
	cout<<"BLOCK_QUEUE :";
	for(p=block_Queue_Head->next;p!=NULL;p=p->next){
		cout<<"->"<<p->id;
	}
	cout<<endl;
	cout<<"-------------------------------------------------------------------------------"<<endl;
	
	//输出各进程的信息
	for(int i=0;i<7;i++){
		if(info[i]=="PRIORITY" || info[i]=="BLOCKTIME" || info[i]=="STARTBLOCK")
			cout<<info[i]<<"\t";
		else
			cout<<info[i]<<"\t\t";
		for(int j=0;j<n;j++){
			switch (i)
			{
			case 0:
				cout<<processInfo[j]->id<<"\t";break;
			case 1:
				cout<<processInfo[j]->priority<<"\t";break;
			case 2:
				cout<<processInfo[j]->cpuTime<<"\t";break;
			case 3:
				cout<<processInfo[j]->allTime<<"\t";break;
			case 4:
				cout<<processInfo[j]->startBlock<<"\t";break;
			case 5:
				cout<<processInfo[j]->blockTime<<"\t";break;
			case 6:
				switch (processInfo[j]->state)
				{
				case -1:
					cout<<"RUNNED\t";break;
				case 0:
					cout<<"BLOCK\t";break;
				case 1:
					cout<<"READY\t";break;
				case 2:
					cout<<"RUN\t";break;
				}
			}
		}
		cout<<endl;
	}
	cout<<"-------------------------------------------------------------------------------"<<endl;
	cout<<"-------------------------------------------------------------------------------"<<endl;
}


//得到队列第一个进程
PCB* GetFirstProc(PCB* head){
	PCB* p=head->next;
	head->next=p->next;
	return p;
}


//是否为空队列
bool EmptyQueue(PCB* head){
	if(head->next==NULL)
		return true;
	else
		return false;
}


//释放空间
void FreeQueue(){
	free(ready_Queue_Head);	//释放就绪队列空间
	free(block_Queue_Head);	//释放堵塞队列空间
	free(processInfo);		//释放输出信息队列空间
	
	//释放执行完毕各进程空间(手动输入时)
// 	PCB* p=NULL;
// 	while(runned_proc!=NULL){
// 		p=runned_proc;
// 		runned_proc=runned_proc->next;
// 		free(p);
// 	}
	free(runned_proc);		//非手动输入时
}


//更新队列
void UpdateQueue(){
	
	timeSlice++;						//时间片+1
	//如果有进程在执行,则更新运行队列信息
	if(running_proc!=NULL){				//cpu有正在执行的进程时
		running_proc->cpuTime++;		//更新运行队列信息
		running_proc->allTime--;
		running_proc->startBlock--;
		running_proc->priority-=3;
	}

	//更新就绪队列
	PCB* p=ready_Queue_Head->next;
	while(p!=NULL){
		p->priority++;		//每等一个时间片,优先权+1
		p=p->next;
	}


	//更新阻塞队列
	p=block_Queue_Head->next;
	PCB* p_before=block_Queue_Head;
	while(p!=NULL){
		p->blockTime--;			//阻塞时间-1

		if(p->blockTime==0){	//阻塞结束
			p->state=READY;		//状态更新
			p_before->next=p->next;
			InsertProcess(p,ready_Queue_Head);		//插入就绪队列
			p=p_before->next;
		}
		else{
			p_before=p;
			p=p->next;
		}
	}
	

	//进行运行调度
	if(running_proc!=NULL){				//有正在执行进程,考虑切换进程
		if(running_proc->allTime==0){	//进程执行完毕
			running_proc->state=RUNNED;

			p=runned_proc->next;		//将进程插入完成队列
			p_before=runned_proc;
			running_proc->next=p;
			p_before->next=running_proc;

			if(ready_Queue_Head->next!=NULL){	//如果还有就绪队列,则切换队列
				running_proc=GetFirstProc(ready_Queue_Head);
				running_proc->state=RUN;
			}	
			else{								//就绪队列为空,则cpu闲置
				running_proc=NULL;
				return;
			}
		}
		else if(running_proc->startBlock==0){				//进程进入阻塞
			running_proc->state=BLOCK;
			InsertProcess(running_proc,block_Queue_Head);
			if(ready_Queue_Head->next!=NULL){	//如果还有就绪队列,则调用一此队列中的进程
				running_proc=GetFirstProc(ready_Queue_Head);
				running_proc->state=RUN;
			}
			else{								//就绪队列为空,则cpu闲置
				running_proc=NULL;
				return;
			}
		}
		else{									//是否切换进程
			if(ready_Queue_Head->next!=NULL)	//就绪队列为空,则不用考虑优先权高低切换进程了
				if(running_proc->priority<ready_Queue_Head->next->priority){	//如果有多个就绪队列,则考虑优先权切换进程
					running_proc->state=READY;
					InsertProcess(running_proc,ready_Queue_Head);
					running_proc=GetFirstProc(ready_Queue_Head);
					running_proc->state=RUN;
				}
		}
	}
	else{			//执行队列为空(CPU闲置),且更新完各队列状态后,考虑将就绪队列是否有可执行的进程
		if(ready_Queue_Head->next!=NULL){
			running_proc=GetFirstProc(ready_Queue_Head);
			running_proc->state=RUN;
		}
	}
}


//运行进程
void FunctionProc(){
	running_proc=GetFirstProc(ready_Queue_Head);
	running_proc->state=RUN;
	while(1){
		if(EmptyQueue(ready_Queue_Head) && EmptyQueue(block_Queue_Head) && running_proc==NULL)
			//就绪队列为空,且阻塞队列为空,且没有正在运行的进程,则结束
			break;

		UpdateQueue();
		cout<<"时间片:"<<timeSlice<<endl;
		ShowQueue();	
	}
	
}


void main(){
	InitQueue();							//初始化就绪、阻塞队列

//方便测试,不手动输入进程各数据,如需手动输入,调用CreateQueue函数
	n=5;
	processInfo=(PCB**)malloc(sizeof(PCB)*n);
	
	PCB p1(0,9,0,3,2,3,READY);
	InsertProcess(&p1,ready_Queue_Head);	//将进程插入相应队列进行排序
	processInfo[0]=&p1;
	
	PCB p2(1,38,0,3,-1,0,READY);
	InsertProcess(&p2,ready_Queue_Head);
	processInfo[1]=&p2;
	
	PCB p3(2,30,0,6,-1,0,READY);
	InsertProcess(&p3,ready_Queue_Head);
	processInfo[2]=&p3;
	
	PCB p4(3,29,0,3,-1,0,READY);
	InsertProcess(&p4,ready_Queue_Head);
	processInfo[3]=&p4;
	
	PCB p5(4,0,0,4,-1,0,READY);
	InsertProcess(&p5,ready_Queue_Head);
	processInfo[4]=&p5;

// 手动输入进程信息函数
// 	CreateProcess();

	ShowQueue();		//显示初始化信息
	FunctionProc();		//运行各进程
	FreeQueue();		//释放占用空间
}

实验结果(时间片执行完后各进程信息)

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
觉得有点帮助的话,麻烦大家留个赞。

  • 8
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值