⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os2.cpp

📁 处理器系统的进程调度编写程序完成单处理机系统中的进程调度
💻 CPP
字号:
//os2.cpp--进程调度:用时间轮片算法
//编译IDE:C++ Builder 的命令行bcc32 编译
//注:本实验中,时间单位以秒计算
//时间片为3秒,每个进程一个所需的运行时间在1~10秒之间,进程间的切换时间为1秒

#include <stdio.h>
#include <iostream.h>
#include <stdlib.h>
#include <time.h>
#include <dos.h>

enum STATE{READY, RUN, OVER};	//进程状态

struct pcb{
	int name;	//进程标识符
	STATE status;	//进程状态
	int needtime;	//进程到运行结束时共需CPU的时间
	int AX, BX, CX,DX;	//进程现场信息,通用寄存器内容
	int PC;		//进程现场信息,程序计数器内容
	int PSW;    //进程现场信息,程序状态字寄存器内容
	int next;   //下一个进程控制块的位置

};

const int q=3;	//时间片大小为3
const int N=10;	//假定系统允许进程个数为10
struct pcb pcbArea[N];	//模拟进程控制块区域的数组

//三个队列的首指针
int run;	//定义指向正在运行进程的进程控制块的指针
struct {
	int head;
	int tail;
}ready;		//定义指向就绪队列的头指针head和尾指针tail
int  pfree; //定义指向空闲进程控制块队列的指针

//初始化函数
void initial()
{
	cout<<"注意:若提示输入的是数字,而输入的是字母或其它字符,则可能会导致死循环"<<endl;

	//将运行队列、就绪队列置空,-1表示空
	run=-1;
	ready.head=ready.tail=-1;

	//将所有的PCB块组织成一个pfree队列
	for(int i=0; i<=N-2; ++i)
		pcbArea[i].next=i+1;
	pcbArea[N-1].next=-1;	//将pfree队列尾结点的指针域置空(即-1)
	pfree=0;	//pfree指向队列头结点
}

//创建进程原语函数
int create()
{
	int i;
	
	if(pfree!=-1){	//空闲进程控制快队列不空
		i=pfree;	//取得空闲进程控制快队列的第一个
		cout<<"\n取得空闲PCB块的i=pfree: i="<<i<<endl;
		pfree=pcbArea[pfree].next;	//指针pfree后移
		//填写进程控制块的内容
		cout<<"Enter the process's NAME(一个唯一正整数作为进程编号): ";
		int subName;
		cin>>subName;
		while(subName<=0){
			cout<<"Enter error! \n请输入一个唯一正整数作为进程编号): ";
			cin>>subName;
		}
		cout<<"Enter the process's STATUS(0表示就绪,1表示运行,2表示结束)"
			<<"\n因为是进程创建时是就绪状态,这里统一输入0): ";
		int subStatus;
		cin>>subStatus;
		while(subStatus!=0){
			cout<<"Enter error! \n请输入(0表示就绪,1表示运行,2表示结束,应该输入0): ";
			cin>>subStatus;
		}
		pcbArea[i].name=subName;
		pcbArea[i].status=READY;

		//挂入就绪队列
		if((ready.head==ready.tail)&&-1==ready.head&&-1==ready.tail){//就绪队列空
			ready.head=i;
			ready.tail=i;
			pcbArea[ready.tail].next=-1;	//队列尾为空
		}
		else{	//一般情况
			pcbArea[ready.tail].next=i;
			ready.tail=i;
			pcbArea[ready.tail].next=-1;
		}

		//随即产生进程运行结束时共占用CPU的时间
		randomize();
		pcbArea[i].needtime=(rand()%10+1);	//进程运行需时为1~10

	}
	else
		return 0;	//创建失败返回

	return pcbArea[i].name;	//创建成功返回进程标识的编号
}

//CPU处理函数
void processRun(int runTime)
{
	while(runTime){
		cout<<"1 second"<<endl;
		sleep(1);
		--runTime;
	}
}

//进程调度
void schedular(int *overCount)
{
	if(-1==run){	//当CPU空闲时才可以进程调度
		if(ready.head!=-1&&ready.tail!=-1){//就绪队列不未空,则摘下就绪队列的头结点,并插入运行队列
			if((ready.head==ready.tail)&&ready.head!=-1&&ready.tail!=-1){//只有最后一个就绪进程了
				run=ready.head;
				ready.head=ready.tail=-1;	//就绪队列置空
			}
			else{	//一般情况
				run=ready.head;
				ready.head=pcbArea[ready.head].next;	//就绪队列头指针后移
			}
		}
	}

	//运行
	if(pcbArea[run].needtime>q){	//进程还需运行时间大于活等于一个时间片
		cout<<"process "<<pcbArea[run].name
			<<" will be RUN one "<<q<<" seconds time, please wait ……"<<endl;
		processRun(q);	//进程运行q秒
		pcbArea[run].needtime-=q;	//还需运行时间减少q
		cout<<"切换情况一:进程未运行完,但由于时间片到,而进行进程调度"<<endl;
	}
	else if(pcbArea[run].needtime==q){	//进程还需运行时间等于一个时间片
		cout<<"process "<<pcbArea[run].name
			<<" will be RUN one "<<q<<" seconds time, please wait ……"<<endl;
		processRun(q);	//进程运行q秒
		pcbArea[run].needtime-=q;
		pcbArea[run].status=OVER;
		cout<<"process "<<pcbArea[run].name<<" is OVER!"<<endl;
		++(*overCount);	//运行完成的进程数加1
		cout<<"切换情况二:时间片到且进程刚好运行完,而进行进程调度"<<endl;
	}
	else{	//进程还需运行时间小于一个时间片
		cout<<"process "<<pcbArea[run].name
			<<" will be RUN  "<<pcbArea[run].needtime<<" seconds time, please wait ……"<<endl;
		processRun(pcbArea[run].needtime);	//进程运行
		pcbArea[run].status=OVER;
		cout<<"process "<<pcbArea[run].name<<" is OVER!"<<endl;
		++(*overCount);	//运行完成的进程数加1
		cout<<"切换情况三:时间片未到,但进程已经运行完,而进行进程调度"<<endl;
	}

	//进程切换的时间1
	cout<<"现在进行进程切换,切换到进程标识为 "<< pcbArea[ready.head].name<<" 切换时间为1秒,wait ……"<<endl;
	cout<<"(switched time) ";
	processRun(1);

	//若进程还未运行完,则将进程改为就绪状态并挂入就绪队列尾
	if(pcbArea[run].status!=OVER){
		pcbArea[run].status=READY;	
		if((ready.head==ready.tail)&&-1==ready.head&&-1==ready.tail){//就绪队列空
			ready.head=run;
			ready.tail=run;
			pcbArea[ready.tail].next=-1;	//队列尾为空
		}
		else{	//一般情况
			pcbArea[ready.tail].next=run;
			ready.tail=run;
			pcbArea[ready.tail].next=-1;
		}
	}

	run=-1;	//将CPU状态改为空闲
}

int main()
{
	initial();	//初始化

	int id=create();
	while(id!=0){	//创建N个进程
		id=create();
	}

	//输出创建成功的10个进程的信息
	cout<<"\n******创建了N个进程以下是N个进程的PCB块信息:*******"<<endl;
	int i=ready.head;
	while(i!=-1){
		cout<<"这是进程标识为 "<<pcbArea[i].name<<" 的PCB块信息:"<<endl;
		cout<<"name: "<<pcbArea[i].name<<endl;
		cout<<"status: "<<(STATE)(pcbArea[i].status)<<endl;
		cout<<"needtime: "<<pcbArea[i].needtime<<endl;
		cout<<"它的next:"<<pcbArea[i].next<<endl;
		i=pcbArea[i].next;
	}
		cout<<"\nrun="<<run<<endl;
		cout<<"ready.head="<<ready.head<<" ready.tail="<<ready.tail<<endl;
		cout<<"pfree="<<pfree<<endl;

		system("PAUSE");
		cout<<endl;

	//进行进程调度
	int overCount=0;	//计数运行完成的进程数
	while(overCount<=9)
		schedular(&overCount);	//被调用函数改写overCount
	
	cout<<"Congratulation to you! "<<overCount<<" Processes haved finished, Bye!"<<endl;
	system("PAUSE");

	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -