操作系统实验-单处理机系统的进程调度

一、实验目的要求

通过模拟进程控制方法和单处理机系统下的进程调度,了解进程的结构、进程的创建与撤销,进程的组织及进程的状态及其转换,掌握进程调度策略。

二、实验材料和仪器设备

Windows操作系统环境下的个人微机。

三、实验内容

实现对N(N的值不小于5)个进程采用动态优先权优先算法的进程调度。
注意:本实验为单机模拟进程调度算法,在程序设计时不需真正地建立线程或进程。
程序要求:为了清楚地观察诸进程的调度过程,程序中应有显示或打印语句,能显示或打印每次被选中进程的进程名,以及运行一次后进程队列的变化。打印程序运行时的初值和运行结果的要求如下:
I)各进程控制块的初始信息。
II)选中运行的进程名以及选中进程运行后的各进程控制块信息,且要求每选中一个进程运行后都要打印。
【提示】
(1)假定系统有5个进程,每一个进程用一个进程控制块PCB来代表,进程控制块的格式为:
进程名
需要运行时间
已用CPU时间
优先数
状态
其中,进程名——作为进程的标识,假设五个进程的进程名分别为P1,P2,P3,P4,P5。
需要运行时间——进程需要运行的单位时间数,以时间片为单位进行计算。
已用CPU时间——进程已经运行的单位时间数,初始值为0。
优先数——赋予进程的优先数,调度时总是选取优先数大的进程先执行。
状态——每个进程的状态可以是就绪 W(Wait)、运行R(Run)、完成F(Finish)三种状态之一。初始状态为“就绪”。
(2)处理机调度程序运行时,为每个进程任意确定它的“优先数”和“需要运行时间”; 可以事先人为地指定,也可以由随机数产生。
(3)处理机调度总是选队首进程运行。就绪进程获得 CPU后都只能运行一个时间片,用已占用CPU时间加1来表示。
(4)进程运行一个时间片后,如果进程已占用 CPU时间已达到所需要的运行时间,则撤消该进程;如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减1(即降低一级),然后把它插入就绪队列等待CPU。
由于本实验是模拟处理器调度,所以,对被选中的进程并不实际的启动运行,而是执行:“优先数-1;已用CPU时间+1;”来模拟进程的一次运行。
提醒注意的是:在实际的系统中,当一个进程被选中运行时,必须恢复进程的现场,让它占有处理器运行,直到出现等待事件或运行结束。在这里省去了这些工作。
(5)每进行一次调度程序都打印一次运行进程、就绪队列、以及各个进程的 PCB,以便进行检查。   
重复以上过程,直到所要进程都完成为止。调度算法的流程图如下:
实验流程

四、实验要求

1、根据给出的流程图认真编写程序,编译环境不限;
2、上机独立调试程序,验证代码的正确性。

五、源代码

#include<iostream>//引入输入输出函数
#include<queue>//引入队列
#include<vector>//引入容器
#include<string>
#define maxn 8//定义最多进程控制块
#define R true//运行态
#define F false//结束态
using namespace std;//使用标准命名空间
struct Node{
    
    
	string name;  //进程名
	int *p;       //指针
	int ndtime;   //需要运行时间
	int prenum;   //优先级数
	int state;    //状态
	}pcb[maxn];//进程控制块
struct cmp{
    
    
	bool operator()(const Node &p,const Node &q){
    
    
		return p.prenum<q.prenum;  //根据优先级数从大到小排序
	}
};
void Init(){
    
    //进程控制块初始化
	printf("以下是进程数为5的情况的展示:\n");
	pcb[1].name = "p1";//名称
	pcb[1].ndtime = 6;//需要运行时间
	pcb[1].prenum = 18;//优先级数
	pcb[1].state = R;
	pcb[2].name = "p2";
	pcb[2].ndtime = 5;
	pcb[2].prenum = 15;
	pcb[2].state = R;
	pcb[3].name = "p3";
	pcb[3].ndtime = 8;
	pcb[3].prenum = 19;
	pcb[3].state = R;
	pcb[4].name = "p4";
	pcb[4].ndtime = 6;
	pcb[4].prenum = 14;
	pcb[4].state = R;
	pcb[5].name = "p5";
	pcb[5].ndtime = 10;
	pcb[5].prenum = 16;
	pcb[5].state = R;
}
void RunQueue(int n)
{
    
    
	priority_queue<Node,vector<Node>,cmp> q;//优先队列<数据类型,容器类型(数组实现的容器),比较的方式>
	vector<string> v;//创建一个vector容器,数据类型为string,动态数组名为v
	for(int i=1;i<=n;++i){
    
    //将五个进程加入队列
		cout<<"将进程"<<pcb[i].name<<"加入队列"<<endl;
		q.push(pcb[i]);
	}
	while(!q.empty()){
    
    //非空一直循环
		Node t = q.top();//让t等于当前队列顶部元素
		q.pop();//移除块内第一个元素
		cout<<"执行进程"<<t.name<<endl;
		v.push_back(t.name);//尾部插入被执行的元素(即刚被执行的进程)
		t.prenum -= 1;//被执行的进程优先级数-1
		t.ndtime -= 1;//被执行的进程需要时间块-1
		if(t.ndtime!=0){
    
    //如果被执行的进程未运行完
			q.push(t);//将进程t置于队列中
			cout<<"将进程"<<t.name<<"再次加入队列"<<endl;
		} 
		else{
    
    //否则被执行的进程运行完,退出队列,状态设为结束
			cout<<"进程"<<t.name<<"退出队列,状态为结束"<<endl;
			t.state = F;
		}
		}
	cout<<"============模拟进程结束============="<<endl;
	cout<<"进程运行序列为:"<<endl;
	for(int i=0;i<v.size();++i){
    
    //vector容器的size()函数输出运行顺序
		cout<<v[i]<<" ";
	}
	cout<<endl;
}

int main(){
    
    
	Init();
	RunQueue(5);
	return 0;
}

六、实验结果

实验结果

猜你喜欢

转载自blog.csdn.net/Barry_kk/article/details/121557200