资源描述
操作系统课程设计报告
题目:一种小型操作系统
班级:计122(杏)
学号:
姓名:贾苏
日期:/06/23
1. 实验平台
(1)软件平台:
开发系统平台:Windows 7 (64)
Microsoft visual c++ 6.0
测试系统平台:Windows 7 (64)
(2) 硬件平台:
cpu:AMD A6-3420 APU
内存:4GB
硬盘:500G
2.所需实现功能及相应阐述:
(1)进程调度管理
为了贴切现实中os,采用RR(轮转调度算法),且不提供顾客显式选取调度算法,即对顾客是透明。
现实中解决器主频为1Ghz~3Ghz,选用中间点为1.5Ghz,得时间片大小为0.7ns ,为以便计算*10,则时间片大小定为7ns。
假设进程之间调度和切换不耗费cpu时间。
(2)死锁检测与解决
检测固然采用是 银行家算法
解决:让顾客选取kill一种进程,释放她所占有所有资源。
(3)虚拟分页调度管理
虚拟分页:给出是逻辑值 访问磁盘 将那个数据块放入到内存中
内存中地址采用一定算法相相应于磁盘地址。
特规定 访存采用是 按字节寻址
内存大小 128KB
外存大小 1MB
即整个系统可以提供1MB逻辑地址空间供进程进行访问(在地址总线足够扫描内存状况下)。
虚拟地址映射采用:直接映射法
规定8kB为一种页面,故内存有16个页面,外存有128个页面。
如果产生了内存已满,便会产生缺页中断,裁减采用FIFO算法,运用一种队列来做。
某些内外存相应表
0
0,128,2*128+0.......
1
1,129,2*128+1.......
2
2,130,2*128+2.......
16
127,128+16,2*128+16.........
(4)I/O中断解决
设中断来自两个方面:
1.DMA输送开始和结束时中断
设定一种宏 定义为DMA一次传播数据量大小->DmaNum
假定为10kb每次
DMA开始:耗费1ns cpu时间进行中断解决
DMA结束:耗费2ns cpu时间进行中断解决
由操作系统课程知,DMA传播数据时不需要CPU干预。
2. 随机中断
发生外部随机中断,cpu无条件及时响应,并执行中断解决程序,同样假设中断解决程序调度和切换不耗费cpu时间。
(5)内存地址越界或内存局限性
进程访问内存时超过了进程所要最大值,此时发生中断,已达到内存保护功能。
内存局限性时即为当前动态地址重定位寄存器中值+进程所需内存大小超过了内存上限,此时进行内存紧凑,同步修改被移动进程中各个关于参数。
3.总体设计
开始
内存管理
查看运营状况
开始运营
外存空间查看
查看cpu运营
内存空间查看
死锁检测与解除
进程信息查看
4.程序所需数据构造及其抽象过程
先定义本次操作系统外设资源,假设有A类资源10个,B类资源5个,C类资源6个->NeedRescourse;
作业中各个进程都需要一种代号->ProcessName,各个进程到来时间不同,故需要记录一下->ArriveTime,每个进程所需要cpu时间是不够->NeedCpuTime,每个进程所需内存空间大小是不同样->NeedMem。
各个进程中任务是不同故需要预先设定本进程中所要执行操作类型->OpKind,如果是计算型直接给出所需要cpu时间即可,如果是I/O型还需要给出所传播数据量大小->NeedTranDataNum,在此可以给OpKind做一种union型构造。
多道程序程序在运营过程中需要对进程所需内存地址进行动态地址重定位,故在系统之中需要设立一种动态地址重定位寄存器,其中内容是下次进程可以使用内存始址->DynReg。
抽象成果:
struct Process{
char ProcessName[10];//进程名字
int ArriveTime; // ns级别
int NeedCpuTime; //此进程所需要时间
int NeedMem; //所需要cpu时间
FlagForOp OpKind; //用于批示是何种操作
int NeedTranDataNum; //给IO用数据块
int OpCpus; //计算类型操作所需cpu时间
int NeedRescourse[3] ;//需要资源数目 NULL代表不需要使用
Process *next;
};
5.详细设计
1.进程信息查看
依次遍历所有链表,并将它们信息依次打印出来。
实现函数名:void ShowProcessInfo()
2.死锁检测和解除
假定本系统中各个所需资源均是独占型资源,在进程运营过程中不再释放,故只需要遍历链表将各个进程中所需资源记录出来,只要不不不大于系统中预设即可,一旦进程所需资源不不大于系统中最大量,予以顾客选取kill一进程,已达到释放资源目。
死锁检测函数:void DeedLock()
void DeedLock_LookNeedRescourse()
死锁解除函数:void DeedLock_KillProcess()
3. 内存空间查看
查看各个进程所占用内存空间,借助于DynReg这个全局变量实行内存空间动态重定位。
实现函数:void LookMem()
4. 查看CPU运营
以CPU角度,查看作业运营状况,
实现函数:void LookCpu()
void LookCpu_ShowRunningProcess()
5. 外存空间查看
外存空间是顾客工作区间,故只要遍历整个进程链表,记录出所有进程占有所有空间即可。
实现函数:void LookDiskMem()
6. 查看运营
查看系统运营中各个资源使用状况:
实现函数: void ShowRunningProcess()
void ShowRunningProcess_CalculateCpuNeed(int*,int)
7. 内存管理
缺页调度算法:FIFO(借助于循环队列实现)
实现函数:void MemToDiskMem()
6.程序运营和调试
1.打开程序初始界面:
按系统提示输入进程数,及其有关各个参数
2.输入完毕后主界面:
顾客可以按下有关选取键实行关于各个操作。
3. 按下1 查看各个进程信息
可以看到刚刚输入各个进程关于信息
4.按下2
5. 按下3 查看运营时CPU使用状况
可见此时系统是安全。
系统出差提示
按下1显示当前各个进程所需资源
然后kill进程1后在查看一下作业中进程,发现被kill进程没有,实现了此功能。
6. 按下4 查看内存使用状况
7. 按下5 查看外存空间
8. 按下6 查看运营状况
9. 按下7 产看内存使用状况
(1) 没有产生缺页
(2) 产生缺页
10.按下9 退出此系统
7.遇到问题
(1) 自己编写映射表相称困难,一度想改用Java语言,在于对C++语言理解不够。
(2) 出错解决没有完全做完,做不够精细,诸多地方直接结束
(3) 对顾客输入数据做类型检查不够充分
(4) delete job时总是浮现系统错误,后debug发现,由于对象之中存在不为空指针,导致出错,故再释放指针所占空间后系统正常运营。
8. 源代码
#include<iostream>
#include<cstring>
#include<windows.h>
#include<cstdlib>
#include"CirQueue.h" //循环队列头文献
using namespace std;
#define MAXMEM 128 //定义本次操作系统最大内存容量
#define MAXDISKMEM 1024 //定义本次操作系统最大外存容量
#define YE 10 //定义本次操作系统分页大小 并 以此实现 虚拟存储
int UsedMAXMEM=0;
int UsedMAXDISKMEM=0;
//定义进程也许用到外部资源
#define A 10
#define B 5
#define C 6
//cpu
#define RR 7 //定义时间片大小为7ns
#define BEFOREDMA 1 //DMA之前所需cpu时间
#define AFTERDMA 2 //DMA之后所需cpu时间
#define ONEDMANUM 10//DMA一次最多传送10kb数据
enum FlagForOp{
IO,Calculate,others
};
int DynReg=0;//定义用于描述动态地址重定位寄存器全局变量
struct Process{
char ProcessName[10];//进程名字
int ArriveTime;// ns级别
int NeedCpuTime;//此进程所需要时间
int NeedMem;//所需要cpu时间
FlagForOp OpKind;//用于批示是何种操作
int NeedTranDataNum;//给IO用数据块
int OpCpus;//计算类型操作所需cpu时间
//假设others不需要其她各个操作。
int NeedRescourse[3];//需要资源数目 NULL代表不需要使用 0——a....
Process *next;
};
class JOB{
Process *p;
Process *head;
Process *head1;//建立一种备用链表
// Process *wait,*runing;//wait 为等待链表 running是正在运营进程
public:
JOB(){
head1=p=head=NULL;//初始化为空
cout<<"Please waiting .The System is initial."<<endl;
Sleep();//暂停一秒 maybe Sleep()
cout<<"System is already. Now you should enter information of you job."<<endl;
int n;
cout<<"enter your job's process num."<<endl;
cin>>n;
while(n){
p=new Process();
cout<<"please enter the name of process."<<endl;
cin>>p->ProcessName;
cout<<"please enter the arrivetime of process."<<endl;
cin>>p->ArriveTime;
cout<<"please enter the NeedCpuTime of process."<<endl;
cin>>p->NeedCpuTime;
cout<<"please enter the NeedMem of process."<<endl;
cin>>p->NeedMem;
while(p->NeedMem>128){
cout<<"This System can't not accept your job!Maybe your job is too large!Please enter a num <128"<<endl;
cin>>p->NeedMem;
}
cout<<"please enter the operation of process.0 to TranDiskNum ,1 to cpu"<<endl;
int nn;
cin>>nn;
if(nn==0){
cout<<"please enter the NeedTranDataNum."<<endl;
cin>>p->NeedTranDataNum;
p->OpKind=IO;
}else{
cout<<"please enter the OpCpus."<<endl;
cin>>p->OpCpus;
p->OpKind=Calculate;
}
cout<<"PLease enter the A,B or C you need"<<endl;
for(int i=0;i<3;i++){
cin>>p->NeedRescourse[i];
}
p->next=NULL;//尾结点为空 表达 一种节点完毕 下面进行插入链表工作
head=SortLinkTable(head,p);
n--;
}//while
LinkCopy();//将本次整顿好链表依次赋值赋给备用链表
Provide_Same_Process_Name();//检查重名现象
}
void Provide_Same_Process_Name();
void VisitLinkTable();
Process* SortLinkTable(Process*,Process*);
void BeginRunning();
void ShowProcessInfo();
void DeedLock();
void DeedLock_KillProcess();
void DeedLock_LookNeedRescourse();
void LookCpu();
void LookCpu_ShowRunningProcess();
void LookMem();
void ShowRunningProcess();
void ShowRunningProcess_CalculateCpuNeed(int*,int);
void LookDiskMem();
void LookMem_ChangeMem();
bool CheckMem();
void LookDiskMem_Change();
void LinkCopy();
void MemToDiskMem();
~JOB(){
delete head;
delete head1;
delete p;
}
};
JOB *job;//设立全局变量
void JOB::Provide_Same_Process_Name(){
system("cls");
char buffer[10];
Process *temp=head1;
Process *temp1=head1;
while(temp){
temp1=temp->next;
while(temp1){
if(strcmp(temp->ProcessName,temp1->ProcessName)==0){
cout<<"Mini_OperationSystem had detect the same name process in your job!"<<endl;
cout<<"This System can't accept this sitution.Please Rename your Process!\nThanks for your corporation!"<<endl;
cout<<"This is ALL your process name:"<<endl;
VisitLinkTable();
cout<<"Enter 1 to rename the former,0 to rename the later!"<<endl;
int n=0;
cin>>n;
cout<<"Now Enter new Name:"<<endl;
if(n==0){
cin>>buffer;
strcpy(temp1->ProcessName,buffer);
}else{
cin>>buffer;
strcpy(temp->ProcessName,buffer);
}
}//end if
temp1=temp1->next;
}//end while temp1
temp=temp->next;
}//while
}
void AgainEnterJOB(){
system("cls");
delete job;
job=new JOB();
}
void JOB::VisitLinkTable(){//不加JOB前缀时候编译但是 加上代表此函数是JOBclass之中
while(head1){
cout<<head1->ProcessName<<endl;
head1=head1->next;
}
cout<<"\nNow ,You can see The List to checkout."<<endl;
}
void JOB::LinkCopy(){
Process *temp=NULL,*temp2=head;
if(head1==NULL){
cout<<"LinkCopy() is Here!"<<endl;
}
if(head1)//不为空时 将其下一种置为空
head1->next=NULL;
head1=NULL;
while(temp2){
//apply a new node
temp=new Process();
strcpy(temp->ProcessName,temp2->ProcessName);
temp->ArriveTime=temp2->ArriveTime;
temp->NeedCpuTime=temp2->NeedCpuTime;
temp->NeedMem=temp2->NeedMem;
if(temp2->OpKind==IO){
temp->OpKind=IO;
temp->NeedTranDataNum=temp2->NeedTranDataNum;
}else{
temp->OpKind=Calculate;
temp->OpCpus=temp2->OpCpus;
}
for(int i=0;i<3;i++){
temp->NeedRescourse[i]=temp2->NeedRescourse[i];
}
//apply end
temp->next=NULL;
//cout<<"copy is right!"<<endl;
if(head1==NULL){
head1=temp;
}else{
Process *k=head1;
while(k->next){//寻找到最后一种节点 不断循环退不出去
k=k->next;
}
k->next=temp;
}
// cout<<"copy is right!"<<endl;
temp2=temp2->next;
}//while
if(head1==NULL)
cout<<"LinkCopy() is out!"<<endl;
system("pause");
}
void JOB::MemToDiskMem(){
system("cls");
CirQueue<int> q(16); //一共定义16个页面 q.EnQueue(e);
int *Mem;
int count=0; //记录下进程数目
Process *temp_head1=head1;
while(temp_head1){
count++;
temp_head1=temp_head1->next;
}
temp_head1=head1;
Mem=new int[count];
int temp_count=0;
while(temp_head1){
int Begin=0;
cout<<"Process:"<<temp_head1->ProcessName<<" memery use situation:"<<endl;
Begin+=temp_head1->NeedMem;
int k=0; //所需页面数目
if(Begin%YE==0){
k=Begin/YE;
}else{
k=Begin/YE+1;
}
Mem[temp_count++]=k;
cout<<k<<"页被占用!"<<endl;
temp_head1=temp_head1->next;
}//end while
cout<<endl;
temp_head1=head1;
cout<<"Want to see 缺页调度过程 Y/N. "<<endl;
char option;
int total=0,AllTotal=0;
cin>>option;
if(option=='y'||option=='Y'){
for(int i=0;i<count;i++){
AllTotal+=Mem[i];
for(int j=0;j<Mem[i];j++){
if(q.EnQueue(true)){
temp_count=0;
while(temp_count<i){
temp_head1=temp_head1->next;
temp_count++;
}
cout<<"Process :"<<temp_head1->ProcessName<<" need mem is loading.ok"<<endl;
temp_head1=head1;
}else{
temp_count=0;
while(temp_count<i){
temp_head1=temp_head1->next;
temp_count++;
}
cout<<"Process :"<<temp_head1->ProcessName<<" need mem is loading error 缺页调度"<<endl;
temp_head1=head1;
total++;
bool flag=q.DeQueue();
if(q.EnQueue(true)){
cout<<"Process :"<<temp_head1->ProcessName<<" need mem is loading ok 缺页调度"<<endl;
}
}
}//for2
cout<<endl;
}//for1
}
cout<<"一共产生了:"<<total<<" 次缺页中断. \n"<<"缺页中断率为:"<<(float)total/AllTotal<<"%"<<endl;
system("pause");
}
void JOB::LookCpu_ShowRunningProcess(){
system("cls");
int NowTime=0;
Process *run=head1;//暂时试用一下 最后需要归还为NULL
Process *wait=head1;// dsvrfgvregrefswgvregegsdgre
int count=0;
while(run){//计算等待运营进程个数
count++;
run=run->next;
}
run=head1;//还原运营链表
//建立一种映射表
char **Run_Process_Name=new char*[count];//申请一种动态二维表
for(int i=0;i<count;i++){//响应二维空间申请完毕
Run_Process_Name[i]=new char[10];
strcpy(Run_Process_Name[i],run->ProcessName);
run=run->next;
}
run=NULL;
int *Run_Process_CpuNeed=new int[count];
//映射表建立完毕
//计算各个进程中所需cpu时间
ShowRunningProcess_CalculateCpuNeed(Run_Process_CpuNeed,count);
Process *priorNode=NULL;
//Process *tail=head;
while(true){
//int time11=wait->ArriveTime;
if(wait&&NowTime>=wait->ArriveTime){
if(run==NULL){
run=wait;
priorNode=run;
}else{//连接到尾部
Process *temp=run;
while(temp->next!=priorNode){//寻找到前驱节点
temp=temp->next;
}
temp->next=wait;//将结点连接上链表
priorNode=wait;
//wait->next=run;
}
wait=wait->next;//释放一种结点
priorNode->next=run;//连接上头部形成 循环链表
}
if(run){
run=run->next; //重新调度
cout<<NowTime<<"->"<<NowTime+RR<<" Process :"<<run->ProcessName<<" is Running"<<endl;
cout<<"cpu 调度下一种运营进程。"<<endl;
NowTime+=RR;
//根据上面建设映射 按名取出所需运营时间
int ALLNeedCpu;
for(int i=0;i<count;i++){
if(strcmp(Run_Process_Name[i],run->ProcessName)==0)
break;
}
ALLNeedCpu=Run_Process_CpuNeed[i];
ALLNeedCpu-=RR;//减去本次运营时间
if(ALLNeedCpu>0){
Run_Process_CpuNeed[i]=ALLNeedCpu;//重新写回到数组中 保持一致性
}else{ //此节点已经做完了 请直接释放
if(run->next==run){
run=NULL;
}else{
Process *k=run;
while(k->next!=run){//寻找当前运营节点前一种结点
k=k->next;
}
k->next=k->next->next;
run=k;
}
}
}// end if(run)
if(wait==NULL&&run==NULL)//没有等待CPU进程了 和 没有正在运营进程 满足退出规定 ->退出
break;
NowTime++;
}//while
system("pause");
LinkCopy();// //将受损链表修复
}
void JOB::ShowRunningProcess(){
system("cls");
int NowTime=0;
Process *run=head1;//暂时试用一下 最后需要归还为NULL
Process *wait=head1;// dsvrfgvregrefswgvregegsdgre
int count=0;
while(run){//计算等待运营进程个数
count++;
run=run->next;
}
run=head1;//还原运营链表
//建立一种映射表
char **Run_Process_Name=new char*[count];//申请一种动态二维表
for(int i=0;i<count;i++){//响应二维空间申请完毕
Run_Process_Name[i]=new char[10];
strcpy(Run_Process_Name[i],run->ProcessName);
run=run->next;
}
run=NULL;
int *Run_Process_CpuNeed=new int[count];
//映射表建立完毕
ShowRunningProcess_CalculateCpuNeed(Run_Process_CpuNeed,count);
Process *priorNode=NULL;
while(true){
//int time11=wait->ArriveTime;
if(wait&&NowTime>=wait->ArriveTime){
if(run==NULL){
run=wait;
priorNode=run;
}else{//连接到尾部
Process *temp=run;
while(temp->next!=priorNode){//寻找到前驱节点
temp=temp->next;
}
temp->next=wait;//将结点连接上链表
priorNode=wait;
//wait->next=run;
}
wait=wait->next;//释放一种结点
priorNode->next=run;//连接上头部形成 循环链表
}
if(run){
run=run->next; //重新调度
cout<<NowTime<<"->"<<NowTime+RR<<" Process :"<<run->ProcessName<<" is Running"<<endl;
cout<<"NeedRescourse:A"<<run->NeedRescourse[0]<<" B"<<run->NeedRescourse[1]<<" c"<<run->NeedRescourse[2]<<" is using."<<endl;
cout<<"cpu 调度下一种运营进程。"<<endl;
NowTime+=RR;
//根据上面建设映射 按名取出所需运营时间
int ALLNeedCpu;
for(int i=0;i<count;i++){
if(strcmp(Run_Process_Name[i],run->ProcessName)==0)
break;
}
ALLNeedCpu=Run_Process_CpuNeed[i];
ALLNeedCpu-=RR;//减去本次运营时间
if(ALLNeedCpu>0){
Run_Process_CpuNeed[i]=ALLNeedCpu;//重新写回到数组中 保持一致性
}else{ //此节点已经做完了 请直接释放
if(run->next==run){
run=NULL;
}else{
Process *k=run;
while(k->next!=run){//寻找当前运营节点前一种结点
k=k->next;
}
k->next=k->next->next;
run=k;
}
}
}// end if(run)
if(wait==NULL&&run==NULL)//没有等待CPU进程了 和 没有正在运营进程 满足退出规定 ->退出
break;
NowTime++;
}//while
sy
展开阅读全文