操作系统课程设计(小型的操作系统)资料

  • 格式:doc
  • 大小:1.92 MB
  • 文档页数:25

操作系统课程设计报告题目:一个小型的操作系统班级:计122(杏)学号:1213023075姓名:贾苏日期:2014/06/231.实验平台(1)软件平台:开发系统平台:Windows 7 (64)Microsoft visual c++ 6.0测试系统平台:Windows 7 (64)(2)硬件平台:cpu:AMD A6-3420 APU内存:4GB硬盘:500G2.所需实现的功能及相应的阐述:(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.总体设计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.按下25.按下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(2000);//暂停一秒 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--;}//whileLinkCopy();//将本次整理好的链表依次赋值赋给备用链表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;cin>>buffer;strcpy(temp1->ProcessName,buffer);}else{cin>>buffer;strcpy(temp->ProcessName,buffer);}}//end iftemp1=temp1->next;}//end while temp1temp=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 nodetemp=new Process();strcpy(temp->ProcessName,temp2->ProcessName);temp->ArriveTime=temp2->ArriveTime;temp->NeedCpuTime=temp2->NeedCpuTime;temp->NeedMem=temp2->NeedMem;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 endtemp->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;}//whileif(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 whilecout<<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;}}}//for2cout<<endl;}//for1}cout<<"一共产生了:"<<total<<" 次缺页中断. \n"<<"缺页中断率为:"<<(float)total/AllTotal<<"%"<<endl;system("pause");}void JOB::LookCpu_ShowRunningProcess(){system("cls");int NowTime=0;Process *run=head1;//临时试用一下最终需要归还为NULLProcess *wait=head1;// dsvrfgvregrefswgvregegsdgreint 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 调度下一个运行的进程。