📄 os3dlg.cpp
字号:
// os3Dlg.cpp : implementation file
//
#include "stdafx.h"
#include "os3.h"
#include "os3Dlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//新加的头文件
#include "iostream.h"
#include "stdio.h"
#include "stdlib.h"
#include "time.h"
#include "conio.h"
//定义各个类
//定义"指令"类
class instruction{
private:
int opcode ; //操作码
int oprand ; //操作数
public:
instruction()
{
opcode = -1;
oprand = -1;
}
void random()
{
opcode = rand()%5;
oprand = rand()%3;
}
int getopcode(){return opcode;}
int getoprand(){return oprand;}
void setopcode(int a){opcode=a;}
void setoprand(int b){oprand=b;}
CString output()
{
CString strOutput,str1,str2;
str1.Format("%d",opcode);
str2.Format("%d",oprand);
strOutput=str1+","+str2+"\r\n";
return strOutput;
}
};
//定义"页表项"类
class item {
private:
int pageNum;//页号
int frameNum;//页架号
public:
item()
{
pageNum=-1;
frameNum=-1;
}
void setpageNum(int pageNum1){pageNum=pageNum1;}
void setframeNum(int frameNum1){frameNum=frameNum1;}
int getpageNum(){return pageNum;}
int getframeNum(){return frameNum;}
CString output()
{
CString strOutput,str1,str2;
str1.Format("%d",pageNum);
str2.Format("%d",frameNum);
strOutput=str1+" "+str2+"\r\n";
return strOutput;
}
};
//定义"页表"类
class pagetable{
public:
item table[20];//每个页表项都是一个二元组:(页号,页架号).此处设置的页表项数目为20
int exp; //替换指针
int size;//页表当前的大小
float count;//缺页次数
float total;//访存的次数
public:
void pagetable1(int temp[10],int size1)
{
size=size1;
for(int i=0;i<=size-1;i++)
{
table[i].setframeNum(temp[i]);//设置页号
table[i].setpageNum(i);//设置页架号
}
total=0;//访存次数为0
count=0;//缺页次数为0
exp=0; //替换指针指向第一个页架(0号页架)
}
void page (int pageNum)
{
total++;//访存次数加1
for(int i=0;i<=19;i++)
if(table[i].getpageNum()==pageNum)
break;//用循环来寻找页号,找到即跳出
if(i<=19)
cout<<"系统中已有相应的页"<<endl; // this line need to be modified
else
{
cout<<"缺页"<<endl;// this line need to be modified
exchange(pageNum);//进行页的替换
}
}
void exchange(int pageNum)
{
table[exp].setpageNum(pageNum); //设置页号
exp=(exp+1)%size;//采用FCFS算法,替换指针指向下一个页架
count++;//缺页次数加一
}
bool free1(int temp[100],int &size1)
{
size1=size;//
for(int i=0;i<=size-1;i++)
temp[i]=table[i].getframeNum();
return true;
}
float frate() //计算缺页率
{
if(total==0)
return 0;
else
return count/total; //缺页次数除以访存次数
}
int decpt() //回收页架
{
if(size<=1)
{
cout<<"错误:页表已无页架可回收"<<endl;// this line need to be modified
return -1;
}
size--;
if(exp==size)
exp=0;
table[size].setpageNum(-1); //清空页号
return table[size].getframeNum();
}
void addpt(int temp) //添加页表项
{
size++;
table[size-1].setframeNum(temp);
exp=size-1;
}
CString output()
{
CString strOutput,str1;
str1.Format("%d",count);
strOutput="\r\n进程发生缺页次数:"+str1+"\r\n";
str1.Format("%d",total);
strOutput+="进程发生访存次数:"+str1+"\r\n";
float fault=frate();
str1.Format("%f",fault);
strOutput+="缺页率:"+str1+"\r\n";
str1.Format("%d",size);
strOutput+= "页表一共有"+str1+"\r\n";
strOutput+= "页号 页架号\r\n";
for(int i=0;i<=size-1;i++)
strOutput+=table[i].output();
strOutput+="\r\n";
return strOutput;
}
int getsize()
{
return size; //返回当前页表大小
}
};
//定义"进程控制块"类
class PCB {
public:
int ID;//进程的ID
int state;//进程的状态 1-ready 2-waiting 3-running
//指令序列
instruction A[30];//假定每个进程至多30条指令 以第一个4号指令结尾
int PC; //指向当前要执行的指令
//虚存
int VMsize; //虚存大小 单位:页
pagetable PT; //页表
//设备
int ownsize; //占有的设备数
int own[5]; //占有的设备号
int ownp; //指向下一个空设备
int request;//申请的设备号
//运行时间
int time;
PCB* next; //指向下一个PCB
PCB(){ID=-1;}
void refresh(int ID1 ,int temp[10] ,int size,int VMsize1)
{
ID=ID1;
state=1;
for(int i=0;i<=28;i++)
{
int t1 =rand()%5;
int t2=0;
if(t1==1)
t2=rand()%20;
else
t2=rand()%3;
A[i].setopcode(t1);
A[i].setoprand(t2);
}
A[29].setopcode(4); //最后一条指令为"退出"(4表示进程退出)
PC=0;//pc指向第一条指令
VMsize=VMsize1;
PT.pagetable1(temp,size);//设置页表项
ownsize=0;//占有的设备数位0
ownp=0; //指向下一个空设备0
for(i=0;i<=4;i++)
own[i]=-1;//没有占用任何设备
request=-1;//没有请求任何设备
time=0;//尚未运行
}
bool page(int pageNum)
{
PT.page(pageNum);//寻找页号
return true;
}
bool free1(int temp[10],int &size)
{
PT.free1(temp,size);//查看页表是否空闲
return true;
}
float frate(){return PT.frate();}//返回缺页率
int decpt(){return PT.decpt();} //回收页表项
void addpt(int temp){PT.addpt(temp);}//添加页表项
CString output()
{
CString strPCBinfo;//存储PCB的输出信息
CString str1;//临时变量
str1.Format("%d",ID);
strPCBinfo="\r\n进程号:"+str1+"\r\n";
str1.Format("%d",state);
strPCBinfo+="状态:"+str1+"\r\n";
switch(state)
{
case 1:
strPCBinfo+="就绪\r\n";
break;
case 2:
strPCBinfo+="等待\r\n";
break;
case 3:
strPCBinfo+="运行\r\n";
break;
}
strPCBinfo+="指令序列:\r\n";
for(int i=0;i<=29;i++)
strPCBinfo+=A[i].output();
str1.Format("%d",PC);
strPCBinfo+="PC: "+str1+"\r\n";
str1.Format("%d",VMsize);
strPCBinfo+="虚存大小:"+str1+" M\r\n";
strPCBinfo+="页表情况如下:\r\n";
strPCBinfo+=PT.output();
str1.Format("%d",ownsize);
strPCBinfo+="占有"+str1+"台设备";
for(i=0; i<=4;i++)
strPCBinfo+=" , ";
strPCBinfo+="\r\n";
str1.Format("%d",request);
strPCBinfo+="请求设备情况(-1为无):"+str1+"\r\n";
str1.Format("%d",time);
strPCBinfo+="运行时间:"+str1+"\r\n";
return strPCBinfo;
}
void timer()
{
time++;//增加运行时间
}
};
//PCB的队列的定义
class pqueque{
private:
PCB * head; //队头指针
PCB * tail; //队尾指针
int length; //队列长度
public:
pqueque()
{
head=tail=new PCB();
length=0;
}
void enqueque(PCB * p) //入队列
{
tail->next=p;
tail=tail->next;
length++;
}
bool dequeque(PCB* &p) //出队列
{
if(length==0)
{
cout<<"队列为空"<<endl;// this line need to be modified
return false;
}
p=head->next;
head->next=head->next->next;
length--;
if(length==0)
tail=head;
return true;
}
void front(PCB* p) //队首元素
{
p->next=head->next;
head->next=p;
length++;
if(length==1)
tail=p;
}
int getlength()
{
return length;
}
CString output()
{
CString strOutput,str1;
str1.Format("%d",length);
strOutput="\r\n队列中一共有"+str1+"个PCB\r\n";
PCB* t=head->next;
for(int i=1;i<=length;i++)
{
strOutput+=t->output();
t=t->next;
}
return strOutput;
}
};
//定义"主存"类
class mainmemory{
private:
int frame[256]; //页架序列 (一共256个页架)0-未用,1-已用
int p; //指向空页架的搜索指针
int freesize; //可用的空页架数
public:
mainmemory()
{
for(int i=0;i<=255;i++)
frame[i]=0;
p=0;
freesize=256;
}
int allocate()
{
if(freesize==0)
{
cout<<"错误:无物理存储空间可分配"<<endl;// this line need to be modified
return -1;
}
if(freesize==1)
{
cout<<"警告:所有页架均已分配"<<endl;// this line need to be modified
freesize--;
frame[p]=1;
return p;
}
int temp=p;
freesize--;
frame[p]=1;
while(frame[p]==1)
p=(p+1)%256;//寻找空页架
return temp;
}
void deallocate(int frameNum ) //释放页
{
p=frameNum;
frame[p]=0;
freesize++;
}
CString output()
{
CString strOutput,str1;
strOutput="\r\n物理空间共有页架数:256 页大小:4K \r\n";
str1.Format("%d",freesize);
strOutput+="其中可用空页架数:"+str1+"\r\n";
for(int i=0;i<=255;i++)
{
str1.Format("%d",frame[i]);
strOutput+=str1+" ";
if((i+1)%16==0)
strOutput+="\r\n";
}
str1.Format("%d",p);
strOutput+="p="+str1+"\r\n";
return strOutput;
}
};
//定义"设备"类
class equip{
public:
int ID; //设备的编号
int state;//设备的状态 0-idle 1-busy
PCB* own ;//占有外设的进程的PCB
pqueque request ;//等待外设的进程队列
public:
void equip1(int ID1)
{
ID=ID1;
state=0; //idle
own =new PCB();
}
int request1(PCB* a) //请求设备
{
if(state==0)
{
own = a;
state=1; //外设忙
return 1;
}
if(state==1)
{
if(a->ID==own->ID)
{
cout<<"错误:该进程申请已经被它占有的设备"<<endl;// this line need to be modified
return -1;
}
else
{
request.enqueque(a); //进入等待队列
return 0;
}
}
return -1;
}
bool deallocate(PCB* &temp) //释放设备
{
if(request.getlength()>0)
{
request.dequeque(temp);
own=temp;
temp->state=1;
temp->own[temp->ownp++]=ID;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -