操作系统课程设计小型的操作系统.docx
《操作系统课程设计小型的操作系统.docx》由会员分享,可在线阅读,更多相关《操作系统课程设计小型的操作系统.docx(31页珍藏版)》请在冰豆网上搜索。
操作系统课程设计小型的操作系统
操作系统课程设计报告
题目:
一个小型的操作系统
班级:
计122(杏)
学号:
**********
姓名:
***
日期:
2014/06/23
1.实验平台
(1)软件平台:
开发系统平台:
Windows7(64)
Microsoftvisualc++6.0
测试系统平台:
Windows7(64)
(2)硬件平台:
cpu:
AMDA6-3420APU
内存:
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开始:
耗费1nscpu时间进行中断处理
DMA结束:
耗费2nscpu时间进行中断处理
由操作系统课程知,DMA传输数据时不需要CPU的干预。
2.随机的中断
发生外部随机中断,cpu无条件的立即响应,并执行中断处理程序,同样的假设中断处理程序的调度和切换不耗费cpu时间。
(5)内存地址越界或内存不足
进程访问内存时超过了进程所要的最大值,此时发生中断,已达到内存保护的功能。
内存不足时即为当前的动态地址重定位寄存器中的值+进程所需的内存大小超过了内存的上限,此时进行内存紧凑,同时修改被移动的进程中的各个有关参数。
3.总体设计
4.程序所需的数据结构及其抽象过程
先定义本次操作系统外设的资源,假设有A类资源10个,B类资源5个,C类资源6个->NeedRescourse;
作业中的各个进程都需要一个代号->ProcessName,各个进程到来的时间不同,故需要记录一下->ArriveTime,每个进程所需要的cpu时间是不够的->NeedCpuTime,每个进程所需的内存空间大小是不一样的->NeedMem。
各个进程中的任务是不同的故需要预先设定本进程中所要执行的操作类型->OpKind,如果是计算型的直接给出所需要的cpu时间即可,如果是I/O型的还需要给出所传输的数据量的大小->NeedTranDataNum,在此可以给OpKind做一个union型的结构。
多道程序程序在运行的过程中需要对进程所需内存的地址进行动态地址重定位,故在系统之中需要设置一个动态地址重定位寄存器,其中的内容是下次进程可以使用的内存始址->DynReg。
抽象结果:
structProcess{
charProcessName[10];//进程的名字
intArriveTime;//ns级别
intNeedCpuTime;//此进程所需要的时间
intNeedMem;//所需要的cpu时间
FlagForOpOpKind;//用于指示是何种操作
intNeedTranDataNum;//给IO用的数据块
intOpCpus;//计算类型的操作所需的cpu时间
intNeedRescourse[3];//需要资源的数目NULL代表不需要使用
Process*next;
};
5.详细设计
1.进程信息查看
依次遍历全部的链表,并将它们的信息依次打印出来。
实现函数名:
voidShowProcessInfo()
2.死锁的检测和解除
假定本系统中的各个所需资源均是独占型资源,在进程运行的过程中不再释放,故只需要遍历链表将各个进程中所需的资源统计出来,只要不大于系统中预设的即可,一旦进程所需的资源大于系统中的最大量,给予用户选择kill一进程,已达到释放资源的目的。
死锁检测函数:
voidDeedLock()
voidDeedLock_LookNeedRescourse()
死锁解除函数:
voidDeedLock_KillProcess()
3.内存空间查看
查看各个进程所占用的内存的空间,借助于DynReg这个全局变量实行内存空间的动态重定位。
实现函数:
voidLookMem()
4.查看CPU运行
以CPU的角度,查看作业的运行情况,
实现函数:
voidLookCpu()
voidLookCpu_ShowRunningProcess()
5.外存空间查看
外存空间是用户的工作区间,故只要遍历整个进程链表,统计出所有进程占有的全部空间即可。
实现函数:
voidLookDiskMem()
6.查看运行
查看系统运行中各个资源的使用情况:
实现函数:
voidShowRunningProcess()
voidShowRunningProcess_CalculateCpuNeed(int*,int)
7.内存管理
缺页调度算法:
FIFO(借助于循环队列实现)
实现函数:
voidMemToDiskMem()
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)deletejob时总是出现系统错误,后debug发现,由于对象之中存在不为空的指针,导致出错,故再释放指针所占空间后系统正常运行。
8.源代码
#include
#include
#include
#include
#include"CirQueue.h"//循环队列的头文件
usingnamespacestd;
#defineMAXMEM128//定义本次操作系统的最大内存容量
#defineMAXDISKMEM1024//定义本次操作系统的最大外存容量
#defineYE10//定义本次操作系统的分页大小并以此实现虚拟存储
intUsedMAXMEM=0;
intUsedMAXDISKMEM=0;
//定义进程可能用到的外部资源
#defineA10
#defineB5
#defineC6
//cpu
#defineRR7//定义时间片大小为7ns
#defineBEFOREDMA1//DMA之前所需的cpu时间
#defineAFTERDMA2//DMA之后所需的cpu时间
#defineONEDMANUM10//DMA一次最多传送10kb的数据
enumFlagForOp{
IO,Calculate,others
};
intDynReg=0;//定义用于描述动态地址重定位寄存器的全局变量
structProcess{
charProcessName[10];//进程的名字
intArriveTime;//ns级别
intNeedCpuTime;//此进程所需要的时间
intNeedMem;//所需要的cpu时间
FlagForOpOpKind;//用于指示是何种操作
intNeedTranDataNum;//给IO用的数据块
intOpCpus;//计算类型的操作所需的cpu时间
//假设others不需要其他的各个操作。
intNeedRescourse[3];//需要资源的数目NULL代表不需要使用0——a....
Process*next;
};
classJOB{
Process*p;
Process*head;
Process*head1;//建立一个备用的链表
//Process*wait,*runing;//wait为等待链表running是正在运行的进程
public:
JOB(){
head1=p=head=NULL;//初始化为空
cout<<"Pleasewaiting.TheSystemisinitial."<Sleep(2000);//暂停一秒maybeSleep()
cout<<"Systemisalready.Nowyoushouldenterinformationofyoujob."<intn;
cout<<"enteryourjob'sprocessnum."<cin>>n;
while(n){
p=newProcess();
cout<<"pleaseenterthenameofprocess."<cin>>p->ProcessName;
cout<<"pleaseenterthearrivetimeofprocess."<cin>>p->ArriveTime;
cout<<"pleaseentertheNeedCpuTimeofprocess."<cin>>p->NeedCpuTime;
cout<<"pleaseentertheNeedMemofprocess."<cin>>p->NeedMem;
while(p->NeedMem>128){
cout<<"ThisSystemcan'tnotacceptyourjob!
Maybeyourjobistoolarge!
Pleaseenteranum<128"<cin>>p->NeedMem;
}
cout<<"pleaseentertheoperationofprocess.0toTranDiskNum,1tocpu"<intnn;
cin>>nn;
if(nn==0){
cout<<"pleaseentertheNeedTranDataNum."<cin>>p->NeedTranDataNum;
p->OpKind=IO;
}else{
cout<<"pleaseentertheOpCpus."<cin>>p->OpCpus;
p->OpKind=Calculate;
}
cout<<"PLeaseentertheA,BorCyouneed"<for(inti=0;i<3;i++){
cin>>p->NeedRescourse[i];
}
p->next=NULL;//尾结点为空表示一个节点的完成下面进行插入链表的工作
head=SortLinkTable(head,p);
n--;
}//while
LinkCopy();//将本次整理好的链表依次赋值赋给备用链表
Provide_Same_Process_Name();//检查重名现象
}
voidProvide_Same_Process_Name();
voidVisitLinkTable();
Process*SortLinkTable(Process*,Process*);
voidBeginRunning();
voidShowProcessInfo();
voidDeedLock();
voidDeedLock_KillProcess();
voidDeedLock_LookNeedRescourse();
voidLookCpu();
voidLookCpu_ShowRunningProcess();
voidLookMem();
voidShowRunningProcess();
voidShowRunningProcess_CalculateCpuNeed(int*,int);
voidLookDiskMem();
voidLookMem_ChangeMem();
boolCheckMem();
voidLookDiskMem_Change();
voidLinkCopy();
voidMemToDiskMem();
~JOB(){
deletehead;
deletehead1;
deletep;
}
};
JOB*job;//设置全局变量
voidJOB:
:
Provide_Same_Process_Name(){
system("cls");
charbuffer[10];
Process*temp=head1;
Process*temp1=head1;
while(temp){
temp1=temp->next;
while(temp1){
if(strcmp(temp->ProcessName,temp1->ProcessName)==0){
cout<<"Mini_OperationSystemhaddetectthesamenameprocessinyourjob!
"<cout<<"ThisSystemcan'tacceptthissitution.PleaseRenameyourProcess!
\nThanksforyourcorporation!
"<cout<<"ThisisALLyourprocessname:
"<VisitLinkTable();
cout<<"Enter1torenametheformer,0torenamethelater!
"<intn=0;
cin>>n;
cout<<"NowEnternewName:
"<if(n==0){
cin>>buffer;
strcpy(temp1->ProcessName,buffer);
}else{
cin>>buffer;
strcpy(temp->ProcessName,buffer);
}
}//endif
temp1=temp1->next;
}//endwhiletemp1
temp=temp->next;
}//while
}
voidAgainEnterJOB(){
system("cls");
deletejob;
job=newJOB();
}
voidJOB:
:
VisitLinkTable(){//不加JOB前缀的时候编译不过加上代表此函数是JOBclass之中的
while(head1){
cout<ProcessName<head1=head1->next;
}
cout<<"\nNow,YoucanseeTheListtocheckout."<}
voidJOB:
:
LinkCopy(){
Process*temp=NULL,*temp2=head;
if(head1==NULL){
cout<<"LinkCopy()isHere!
"<}
if(head1)//不为空时将其下一个置为空
head1->next=NULL;
head1=NULL;
while(temp2){
//applyanewnode
temp=newProcess();
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(inti=0;i<3;i++){
temp->NeedRescourse[i]=temp2->NeedRescourse[i];
}
//applyend
temp->next=NULL;
//cout<<"copyisright!
"<if(head1==NULL){
head1=temp;
}else{
Process*k=head1;
while(k->next){//寻找到最后一个节点不断的循环退不出去
k=k->next;
}
k->next=temp;
}
//cout<<"copyisright!
"<temp2=temp2->next;
}//while
if(head1==NULL)
cout<<"LinkCopy()isout!
"<system("pause");
}
voidJOB:
:
MemToDiskMem(){
system("cls");
CirQueueq(16);//一共定义的16个页面q.EnQueue(e);
int*Mem;
intcount=0;//记录下进程的数目
Process*temp_head1=head1;
while(temp_head1){
count++;
temp_head1=temp_head1->next;
}
temp_head1=head1;
Mem=newint[count];
inttemp_count=0;
while(temp_head1){
intBegin=0;
cout<<"Process:
"<ProcessName<<"memeryusesituation:
"<Begin+=temp_head1->NeedMem;
intk=0;//所需的页面数目
if(Begin%YE==0){
k=Begin/YE;
}else{
k=Begin/YE+1;
}
Mem[temp_count++]=k;
cout<"<temp_head1=temp_head1->next;
}//endwhile
cout<temp_head1=head1;
cout<<"Wanttosee缺页调度过程Y/N."<charoption;
inttotal=0,AllTotal=0;
cin>>option;
if(option=='y'||option=='Y'){
for(inti=0;iAllTotal+=Mem[i];
for(intj=0;jif(q.EnQueue(true)){
temp_count=0;
while(temp_count
temp_head1=temp_head1->next;
temp_count++;
}
cout<<"Process:
"<ProcessName<<"needmemisloading.ok"<temp_head1=head1;
}else{
temp_count=0;
while(temp_count
temp_head1=temp_head1->next;
temp_count++;
}
cout<<"Process:
"<ProcessName<<"needmemisloadingerror缺页调度"<temp_head1=head1;
total++;
boolflag=q.DeQueue();
if(q.EnQueue(true)){
cout<<"Process:
"<ProcessName<<"needmemisloadingok缺页调度"<