操作系统:用C++模拟进程调度
1.内容与要求:
1)创建10个进程的PCB,每个PCB包括:进程名、进程状态、优先级(1~10)、需要在处理机上执行的时间(ms)、队列指针等;
2)初始化10个PCB(产生随机数0或1,分别表示进程处于就绪态或等待态);
3)根据调度算法选择一个就绪进程在CPU上执行;
4)在进程执行过程中,产生随机数0或1,该随机数为1时,将等待队列中的第一个PCB加入就绪队列的对尾;
5)在进程执行过程中,产生一个随机数,表示执行进程能在处理机上执行的时间,如果随机时间大于总需要的时间,则执行完成。如果小于,则从总时间中减去执行时间。
6)如果执行进程没有执行完成。则产生随机数0或1,当该随机数为0时,将执行进程加入就绪队列对尾;否则,将执行进程加入等待队列对尾;
7)一直到就绪队列为空,程序执行结束。
2.调度算法的要求:
1)使用基于先进先出的调度算法
2)使用基于优先级的调度算法
3)使用基于最短执行时间的调度算法
3.代码实现:
#include "iostream"
#include "stdlib.h"
#include "unistd.h"
using namespace std;
//PCB数据结构
typedef struct PCB{
int name;
int status;
int priority;
int time;
}PCB;
typedef struct QNode{
PCB data;
struct QNode *next;
}QNode;
typedef struct {
QNode *front; //队头指针
QNode *rear; //队尾指针
}LinkQueue;
//初始化队列
bool InitQueue(LinkQueue &Q){
Q.front=Q.rear=new QNode;
Q.front->next=NULL;
return true;
}
//入队
bool EnQueue(LinkQueue &Q,PCB e){
QNode* p=new QNode;
p->data=e;
p->next=NULL; Q.rear->next=p;
Q.rear=p;
// p=NULL;
return true;
}
//出队
bool DeQueue(LinkQueue &Q){
if(Q.front==Q.rear)
return false;
else {
QNode *p = Q.front->next;
Q.front->next = p->next;
if (Q.rear == p)
Q.rear = Q.front;
delete p;
return true;
}
}
//取队头
PCB GetHead(LinkQueue &Q){
PCB m;
m.name=-1;m.time=0;m.priority=-1;m.status=0;
if(Q.front!=Q.rear)
return Q.front->next->data;
else{
return m;
}
}
//遍历队列
void TravelQueue(LinkQueue Q){
QNode* p=Q.front;
if(p->next==NULL)
return;
while (p->next->next){
cout<<p->next->data.name<<"-->";
p=p->next;
}
cout<<p->next->data.name;
p=NULL;
}
//定义删除队列节点函数
void DeleteNode(LinkQueue &Q,PCB e){
QNode* p=Q.front;
while (p->next->next){
if(p->next->data.name==e.name){
QNode* s=p->next;
p->next=s->next;
delete s;
break;
}
p=p->next;
}
if(p->next->data.name==e.name)
{
Q.rear=p;
Q.rear->next=NULL;
}
}
//定义获取0/1随机数函数
int GetSrand(){
srand(time(0));
int m=rand()%2;
return m;
}
//定义获取1-10之间的随机数,作为该进程要花费的时间
int GetTime(){
srand(time(0));
int m=(rand()%10+1);
return m;
}
//打印等待队列和就绪队列函数
void Print(LinkQueue &Q1,LinkQueue &Q2){
cout<<"等待队列为:";
TravelQueue(Q1);
cout<<endl;
cout<<"就绪队列为:";
TravelQueue(Q2);
cout<<endl;
}
//基于最短执行时间调度算法的获得最小时间函数
PCB GetLessTime(LinkQueue &Q){
QNode* p=Q.front;
QNode* q=Q.front;
PCB m;
int time=11;
while(p->next){
if(p->next->data.time<=time)
time=p->next->data.time;
p=p->next;
}
p=NULL;
while(q->next){
if(q->next->data.time==time){
m=q->next->data;
break;
}
q=q->next;
}
q=NULL;
return m;
}
//基于最大优先级调度算法的获得最大优先级函数
PCB GetPriority(LinkQueue &Q){
QNode* p=Q.front;
QNode* q=Q.front;
int priority=0;
PCB m;
while(p->next){
if(p->next->data.priority>priority)
priority=p->next->data.priority;
p=p->next;
}
p=NULL;
while(q->next){
if(q->next->data.priority==priority){
m=q->next->data;
break;
}
q=q->next;
}
q=NULL;
return m;
}
//基于先进先出调度算法
void No1(LinkQueue Q1,LinkQueue Q2){
int i=0;
while(Q2.front->next!=NULL){
cout<<"-------------------------"<<endl;
cout<<"第"<<i+1<<"轮"<<endl;
PCB first= GetHead(Q2); //取队头
DeQueue(Q2); //出队
cout<<"当前执行进程为:"<<first.name<<endl;
Print(Q1,Q2); //打印此时的等待队列和就绪队列
int Srand=GetSrand(); //得到一个随机数0/1
sleep(1); //延时
cout<<"#进程执行过程中产生的随机数(0/1)为:"<<Srand<<endl;
if(Srand==0)
cout<<"#由于产生的随机数为0,不操作"<<endl;
else
{
cout<<"#由于产生的随机数为1,将等待队列中的第一个PCB加入就绪队列的队尾"<<endl;
PCB temp= GetHead(Q1);
if(temp.name!=-1) {
EnQueue(Q2, temp);
DeQueue(Q1);
}
cout<<"当前执行进程为:"<<first.name<<endl;
Print(Q1,Q2);
}
int Time=GetTime();
cout<<"#进程执行过程中执行进程能在处理机上执行的时间为:"<<Time<<endl;
if(first.time<=Time){
cout<<"#处理机分配的时间足够,选取的进程将被执行完毕"<<endl;
cout<<"#这一轮最终的等待队列和就绪队列为:"<<endl;
Print(Q1,Q2);
}
else {
first.time = first.time - Time;
int s = GetSrand();
sleep(1);
cout << "#选取的进程时间片被用完,此时生成一个随机数:" << s << endl;
if (s == 0) {
cout << "#将该执行进程加入就绪队列队尾后这一轮最终的等待队列和就绪队列为:" << endl;
EnQueue(Q2, first);
Print(Q1, Q2);
} else {
cout << "#将该执行进程加入等待队列队尾后这一轮最终的等待队列和就绪队列为:" << endl;
EnQueue(Q1, first);
Print(Q1, Q2);
}
}
i++;
}
}
//基于优先级的调度算法
void No2(LinkQueue &Q1,LinkQueue &Q2){
int i=0;
while(Q2.front->next!=NULL){
cout<<"-------------------------"<<endl;
cout<<"第"<<i+1<<"轮"<<endl;
// cout<<"基于优先级选择一个进程运行,此时两个队列为:"<<endl;
PCB first= GetPriority(Q2);
DeleteNode(Q2,first);
cout<<"当前执行进程为:"<<first.name<<endl;
Print(Q1,Q2);
int Srand=GetSrand();
sleep(1);
cout<<"进程执行过程中产生的随机数(0/1)为:"<<Srand<<endl;
if(Srand==0)
cout<<"由于产生的随机数为0,不操作"<<endl;
else
{
cout<<"由于产生的随机数为1,将等待队列中的第一个PCB加入就绪队列的队尾"<<endl;
PCB temp= GetHead(Q1);
if(temp.name!=-1){
EnQueue(Q2,temp);
DeQueue(Q1);
}
cout<<"当前执行进程为:"<<first.name<<endl;
Print(Q1,Q2);
}
int Time=GetTime();
cout<<"进程执行过程中执行进程能在处理机上执行的时间为:"<<Time<<endl;
if(first.time<=Time){
cout<<"处理机分配的时间足够,选取的进程将被执行完毕"<<endl;
cout<<"这一轮最终的等待队列和就绪队列为:"<<endl;
Print(Q1,Q2);
}
else{
first.time= first.time-Time;
int s=GetSrand();
sleep(1);
cout<<"选取的进程时间片被用完,此时生成一个随机数:"<<s<<endl;
if(s==0){
cout<<"将该执行进程加入就绪队列队尾后这一轮最终的等待队列和就绪队列为:"<<endl;
EnQueue(Q2,first);
Print(Q1,Q2);
}
else{
cout<<"将该执行进程加入等待队列队尾后这一轮最终的等待队列和就绪队列为:"<<endl;
EnQueue(Q1,first);
Print(Q1,Q2);
}
}
i++;
}
}
//基于最短执行时间调度算法
void No3(LinkQueue &Q1,LinkQueue &Q2){
int i=0;
while(Q2.front->next!=NULL){
cout<<"-------------------------"<<endl;
cout<<"第"<<i+1<<"轮"<<endl;
PCB first=GetLessTime(Q2);//取最短时间进程
DeleteNode(Q2, first); //删除该节点
cout<<"当前运行进程为:"<<first.name<<endl;
Print(Q1,Q2);
int Srand=GetSrand();
sleep(1);
cout<<"#进程执行过程中产生的随机数(0/1)为:"<<Srand<<endl;
if(Srand==0)
cout<<"#产生的随机数为0,不操作"<<endl;
else
{
cout<<"#产生的随机数为1,将等待队列中的第一个PCB加入就绪队列的队尾"<<endl;
PCB temp= GetHead(Q1);
// cout<<temp.time<<temp.name<<temp.priority<<temp.status<<endl;
if(temp.name!=-1){
EnQueue(Q2, temp);
DeQueue(Q1);
}
cout<<"当前运行进程为:"<<first.name<<endl;
Print(Q1,Q2);
}
int Time=GetTime();
cout<<"#进程执行过程中执行进程能在处理机上执行的时间为:"<<Time<<endl;
if(first.time<=Time){
cout<<"#处理机分配的时间足够,选取的进程将被执行完毕"<<endl;
cout<<"#这一轮最终的等待队列和就绪队列为:"<<endl;
Print(Q1,Q2);
}
else{
first.time=first.time-Time;
int s=GetSrand();
sleep(1);
cout<<"#选取的进程时间片被用完,此时生成一个随机数:"<<s<<endl;
if(s==0){
cout<<"#执行进程加入就绪队列队尾,最终的等待队列和就绪队列为:"<<endl;
EnQueue(Q2,first);
Print(Q1,Q2);
}
else{
cout<<"#执行进程加入等待队列队尾,最终的等待队列和就绪队列为:"<<endl;
EnQueue(Q1,first);
Print(Q1,Q2);
}
}
i++;
}
}
int main(){
LinkQueue Q1,Q2; //定义Q1等待队列,Q2就绪队列。
InitQueue(Q1); //初始化Q1等待队列
InitQueue(Q2);//初始化Q2就绪队列
PCB p[10];//定义PCB类型的数组
int choice;
//创建并初始化十个PCB
for(int i=0;i<10;i++) {
cout<<"请输入第"<<i+1<<"个PCB的进程名,优先级:";
cin>>p[i].name>>p[i].priority; //手动输入PCB的进程名和优先级
//随机得到各个PCB的运行时间和状态
p[i].time=GetTime();
p[i].status=GetSrand();
cout<<"该进程要花费的时间为:"<<p[i].time<<endl;
cout<<"该进程的状态为:"<<p[i].status<<endl;
}
//根据进程的状态,进等待队列还是就绪队列
for(int i=0;i<10;i++){
if(p[i].status==1)
EnQueue(Q1,p[i]); //状态为1则入等待队列
else
EnQueue(Q2,p[i]); //状态为0则入就绪队列
}
cout<<"-------------------------"<<endl;
cout<<"输入十个PCB后等待队列和就绪队列分别如下:"<<endl;
Print(Q1,Q2);
cout<<"-------------------------"<<endl;
cout<<"请输入您的选择(选项:1,2,3)"<<endl;
cout<<"1.基于先进先出调度算法"<<endl;
cout<<"2.基于优先级的调度算法"<<endl;
cout<<"3.基于最短执行时间调度算法"<<endl;
cout<<"您的选择为:";
cin>>choice;
switch(choice){
case 1:No1(Q1,Q2); break; //基于先进先出调度算法
case 2:No2(Q1,Q2); break; //基于优先级的调度算法
case 3:No3(Q1,Q2); break; //基于最短执行时间的调度算法
default: cout<<"输入有误!"<<endl; break; //其他
}
return 0;
}
4.运行结果截图:
1)输入十个PCB:
2)程序产生随机数0/1,将这十个PCB分成就绪队列和等待队列:
3)进入算法选择页面:
4)进程开始调度,一直到就绪队列为空时程序运行结束: