操作系统课程设计报告
题目:一个小型的操作系统 学号:**********
班级:计122(杏) 姓名:***
日期:2014/06/23
1.实验平台 (1)软件平台:
开发系统平台:Windows 7 () Microsoft visual c++ 6.0 测试系统平台:Windows 7 () (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 1 2 0,128,2*128+0....... 1,129,2*128+1....... 2,130,2*128+2....... 16
(4)I/O中断处理 设中断来自两个方面:
1.DMA输送开始和结束时的中断
127,128+16,2*128+16......... 设定一个宏 定义为DMA一次传输的数据量的大小->DmaNum 假定为10kb每次
DMA开始:耗费1ns cpu时间进行中断处理
DMA结束:耗费2ns cpu时间进行中断处理
由操作系统课程知,DMA传输数据时不需要CPU的干预。 2.随机的中断
发生外部随机中断,cpu无条件的立即响应,并执行中断处理程序,同样的假设中断处理程序的调度和切换不耗费cpu时间。
(5)内存地址越界或内存不足
进程访问内存时超过了进程所要的最大值,此时发生中断,已达到内存保护的功能。
内存不足时即为当前的动态地址重定位寄存器中的值+进程所需的内存大小超过了内存的上限,此时进行内存紧凑,同时修改被移动的进程中的各个有关参数。 3.总体设计
4.程序所需的数据结构及其抽象过程
进程信息查看 死锁检测与解除 内存空间查看 查看cpu运行 外存空间查看 查看运行情况 开始运行 内存管理 开始 先定义本次操作系统外设的资源,假设有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 #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{ }; int DynReg=0;//定义用于描述动态地址重定位寄存器的全局变量 struct Process{ }; class JOB{ Process *p; Process *head; Process *head1;//建立一个备用的链表 // Process *wait,*runing; //wait 为等待链表 running是正在运行的进程 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; IO,Calculate,others public: JOB(){ head1=p=head=NULL;//初始化为空 cout<<\"Please waiting .The System is initial.\"< Sleep(2000);//暂停一秒 maybe Sleep() cout<<\"System is already. Now you should enter information of you job.\"< p=new Process(); cout<<\"please enter the name of process.\"< cout<<\"please enter the arrivetime of process.\"< cout<<\"please enter the NeedCpuTime of process.\"< cout<<\"please enter the NeedMem of process.\"< cout<<\"please enter the operation of process.0 to TranDiskNum ,1 to cpu\"< cout<<\"please enter the NeedTranDataNum.\"< cout<<\"This System can't not accept your job! Maybe your job is too large! Please enter a num <128\"< }else{ } cout<<\"PLease enter the A,B or C you need\"< cout<<\"please enter the OpCpus.\"< 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(){ } }; 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!\"< delete head; delete head1; delete p; corporation!\"< cout<<\"Now Enter new Name:\"< 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(){ } void JOB::VisitLinkTable(){//不加JOB前缀的时候编译不过 加上代表此函数是JOBclass之中的 while(head1){ } cout< system(\"cls\"); delete job; job=new JOB(); cout<<\"\\nNow , You can see The List to checkout.\"< Process *temp=NULL,*temp2=head; if(head1==NULL){ cout<<\"LinkCopy() is Here!\"< //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!\"< }else{ Process *k=head1; while(k->next){//寻找到最后一个节点 不断的循环退不出去 } // cout<<\"copy is right!\"< k->next=temp; k=k->next; temp2=temp2->next; }//while if(head1==NULL) cout<<\"LinkCopy() is out!\"< system(\"cls\"); CirQueue 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: \"< int k=0; //所需的页面数目 if(Begin%YE==0){ k=Begin/YE; }else{ k=Begin/YE+1; } Mem[temp_count++]=k; cout< cout< cout<<\"Want to see 缺页调度过程 Y/N. \"< if(option=='y'||option=='Y'){ for(int i=0;i for(int j=0;j temp_count=0; while(temp_counttemp_head1=temp_head1->next; } temp_count++; cout<<\"Process :\"< temp_count=0; while(temp_counttemp_head1=temp_head1->next; temp_count++; } cout<<\"Process :\"< total++; bool flag=q.DeQueue(); if(q.EnQueue(true)){ cout<<\"Process :\"< system(\"cls\"); int NowTime=0; Process *run=head1;//临时试用一下 最终需要归还为NULL Process *wait=head1;// dsvrfgvregrefswgvregegsdgre int count=0; while(run){//计算等待运行的进程的个数 cout<<\"一生了:\"< } }//for2 cout< count++; //建立一个映射表 char **Run_Process_Name=new char*[count];//申请一个动态的二维表 for(int i=0;i run=head1;//还原运行链表 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时间 Process *priorNode=NULL; //Process *tail=head; while(true){ //int time11=wait->ArriveTime; if(wait&&NowTime>=wait->ArriveTime){ if(run==NULL){ ShowRunningProcess_CalculateCpuNeed(Run_Process_CpuNeed,count); //映射表建立完毕 run=wait; priorNode=run; }else{//连接到尾部 Process *temp=run; } if(run){ run=run->next; //重新调度 cout< 按名取出所需运行的时间 } wait=wait->next;//释放一个结点 priorNode->next=run;//连接上头部形成 循环链表 while(temp->next!=priorNode){//寻找到前驱节点 } temp->next=wait;//将结点连接上链表 priorNode=wait; //wait->next=run; temp=temp->next; int ALLNeedCpu; for(int i=0;i } ALLNeedCpu=Run_Process_CpuNeed[i]; break; 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->next=k->next->next; run=k; k=k->next; }// 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 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->next=wait;//将结点连接上链表 priorNode=wait; //wait->next=run; temp=temp->next; } wait=wait->next;//释放一个结点 priorNode->next=run;//连接上头部形成 循环链表 if(run){ run=run->next; //重新调度 cout< is using.\"< 按名取出所需运行的时间 int ALLNeedCpu; for(int i=0;i 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_CalculateCpuNeed(int*Run_Process_CpuNeed,int count){ Process *temp=head1; for(int i=0;i 退出 -> } } if(temp->OpKind==IO){ if(temp->NeedTranDataNum%ONEDMANUM==0){ ALLNeedCpu+=(temp->NeedTranDataNum/ONEDMANUM)*(BEFOREDMA+AFTERDMA); }else{ } ALLNeedCpu+=(temp->NeedTranDataNum/ONEDMANUM+1)*(BEFOREDMA+AFTERDMA); }else{ } Run_Process_CpuNeed[i]=ALLNeedCpu; ALLNeedCpu+=temp->OpCpus; temp=temp->next; void JOB::ShowProcessInfo(){ system(\"cls\"); } void JOB::DeedLock(){ system(\"cls\"); Process *temp=head1; int count=0; while(temp){ } cout<<\"enter anykey return main() .\"< <<\ temp=temp->next; cout<<'\\n'; count++; Process *temp=head1; int LocalA=0,LocalB=0,LocalC=0; while(temp){ LocalA+=temp->NeedRescourse[0]; LocalB+=temp->NeedRescourse[1]; LocalB+=temp->NeedRescourse[2]; temp=temp->next; } if(LocalA>A||LocalB>B||LocalC>C){ cout<<\"NeedRescourse is over!\"< if(n==1){ DeedLock_LookNeedRescourse(); } }else{ cout<<\"Your JOb is ok! System Now is safe!\"< } void JOB::DeedLock_LookNeedRescourse(){ Process* temp=head1; cout<<\"\\nNeedRescourse: A B C\\n\"; while(temp){ cout< \"< \"< system(\"pause\"); cout<<\"Are you want to Kill one Process to Release NeedRescourse.Y/N\"< cin>>option; if(option=='Y'||option=='y'){ DeedLock_KillProcess(); } } void JOB::DeedLock_KillProcess(){ Process *temp=head; cout<<\"Enter 1,2,....to Kill 1th,2th,....Process.\"< if(count==1){ head=head->next; }else{ Process *temp2=head; n=1; \"< } while((n+1) n++; temp2=temp2->next; LinkCopy(); } void JOB::LookCpu(){ system(\"cls\"); LookCpu_ShowRunningProcess(); } void JOB::LookMem(){ int Mem[128]; int DiskMem[1024]; } bool JOB::CheckMem(){//检查虚拟存储器是否可以接纳 } void JOB::LookDiskMem(){ int sum=0; Process *temp=head; while(temp){ sum+=temp->NeedMem; int sum=0; Process *temp=head; while(temp){ } if(sum>=1024) else return true; return false; sum+=temp->NeedMem; memset(Mem,0,128); memset(DiskMem,0,1024); DynReg=0; Process *temp=head1; while(temp&&DynReg<=128){ } cout<<\"Enter Any Key to Return Main().\"< } temp=temp->next; if(sum>1024){ cout<<\"This system DiskMemery is out!\\n please enter 1 to change you process NeedMem \\nelse system may have something wrong\"< cout<<\"Enter 1 to Change Memery size else System will exit.\"< LookDiskMem_Change(); }else{ exit(0); } void JOB::LookDiskMem_Change(){ } Process *temp=head; while(temp){ } temp=head; while(temp){ } delete head1; LinkCopy();//保持链表的一致性 char n; cout<<\"Change \"< if(n=='Y'||n=='y'){ cout<<\"Enter you New NeedMem:\"< cout<<\"Process :\"< } }else{ } cout<<\"enter anykey return main() .\"< }else{ } temp=temp->next; cout<<\"Error! Enter a undefined character.\"< void JOB::BeginRunning(){ while(true){ system(\"cls\"); cout<<\"Mini Operation is Running. Please wait a second!\"< //cout<<\"Debug p!:\"< Process *k=head; Process *k1=head; while(k1->next&&k1->ArriveTime if(k1->ArriveTime k1->next=p;p->next=NULL; k=k1; k1=k1->next; head->next=NULL; p->next=head; head=p; return head; p->next=NULL; head=p; return head; }else{//插入两点之间 } return head; p->next=k1;k->next=p; cout<<\" 7 to see 查看内存管理\"< } } case 1: ShowProcessInfo(); break; case 2: DeedLock(); break; case 3: LookCpu(); break; case 4: LookMem(); break; case 5: LookDiskMem(); break; case 6: ShowRunningProcess(); break; case 7: MemToDiskMem(); break; case 8: AgainEnterJOB(); break; case 9: cout<<\"Bye-Bye.\"< cout<<\"You choice maybe wrong!\\nplease follow me instruction,Thanks for your corporation.\"< cout<<\"Welocme to Mini-OpeartionSystem.\"< 因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- efsc.cn 版权所有 赣ICP备2024042792号-1
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务