文档库

最新最全的文档下载
当前位置:文档库 > 操作系统课程设计(小型的操作系统)资料

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

操作系统课程设计报告

题目:一个小型的操作系统

班级:计122(杏)

学号:1213023075

姓名:贾苏

日期:2014/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.总体设计

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

#include

#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{

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."<

Sleep(2000);//暂停一秒 maybe Sleep()

cout<<"System is already. Now you should enter information of you job."<

int n;

cout<<"enter your job's process num."<

cin>>n;

while(n){

p=new Process();

cout<<"please enter the name of process."<

cin>>p->ProcessName;

cout<<"please enter the arrivetime of process."<

cin>>p->ArriveTime;

cout<<"please enter the NeedCpuTime of process."<

cin>>p->NeedCpuTime;

cout<<"please enter the NeedMem of process."<

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"<

cin>>p->NeedMem;

}

cout<<"please enter the operation of process.0 to TranDiskNum ,1 to cpu"<

int nn;

cin>>nn;

if(nn==0){

cout<<"please enter the NeedTranDataNum."<

cin>>p->NeedTranDataNum;

p->OpKind=IO;

}else{

cout<<"please enter the OpCpus."<

cin>>p->OpCpus;

p->OpKind=Calculate;

}

cout<<"PLease enter the A,B or C you need"<

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!"<

cout<<"This System can't accept this sitution.Please Rename your Process! \nThanks for your corporation!"<

cout<<"This is ALL your process name:"<

VisitLinkTable();

cout<<"Enter 1 to rename the former,0 to rename the later!"<

int n=0;

cin>>n;

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(){

system("cls");

delete job;

job=new JOB();

}

void JOB::VisitLinkTable(){//不加JOB前缀的时候编译不过加上代表此函数是JOBclass之中的while(head1){

cout<ProcessName<

head1=head1->next;

}

cout<<"\nNow , You can see The List to checkout."<

}

void JOB::LinkCopy(){

Process *temp=NULL,*temp2=head;

if(head1==NULL){

cout<<"LinkCopy() is Here!"<

}

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;

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!"<

if(head1==NULL){

head1=temp;

}else{

Process *k=head1;

while(k->next){//寻找到最后一个节点不断的循环退不出去

k=k->next;

}

k->next=temp;

}

// cout<<"copy is right!"<

temp2=temp2->next;

}//while

if(head1==NULL)

cout<<"LinkCopy() is out!"<

system("pause");

}

void JOB::MemToDiskMem(){

system("cls");

CirQueue 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: "<ProcessName<<" memery use situation:"<

Begin+=temp_head1->NeedMem;

int k=0; //所需的页面数目

if(Begin%YE==0){

k=Begin/YE;

}else{

k=Begin/YE+1;

}

Mem[temp_count++]=k;

cout<

temp_head1=temp_head1->next;

}//end while

cout<

temp_head1=head1;

cout<<"Want to see 缺页调度过程 Y/N. "<

char option;

int total=0,AllTotal=0;

cin>>option;

if(option=='y'||option=='Y'){

for(int i=0;i

AllTotal+=Mem[i];

for(int j=0;j

if(q.EnQueue(true)){

temp_count=0;

while(temp_count

temp_head1=temp_head1->next;

temp_count++;

}

cout<<"Process :"<ProcessName<<" need mem is loading.ok"<

temp_head1=head1;

}else{

temp_count=0;

while(temp_count

temp_head1=temp_head1->next;

temp_count++;

}

cout<<"Process :"<ProcessName<<" need mem is loading error 缺页调度"<

temp_head1=head1;

total++;

bool flag=q.DeQueue();

if(q.EnQueue(true)){

cout<<"Process :"<ProcessName<<" need mem is loading ok 缺页调度"<

}

}

}//for2

cout<

}//for1

}

cout<<"一共产生了:"<

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

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<"<ProcessName<<" is Running"<

cout<<"cpu 调度下一个运行的进程。"<

NowTime+=RR;

//依据上面建设的映射按名取出所需运行的时间

int ALLNeedCpu;

for(int i=0;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

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<"<ProcessName<<" is Running"<

cout<<"NeedRescourse: A"<NeedRescourse[0]<<" B"<NeedRescourse[1]<<" c"<NeedRescourse[2]<<" is using."<

cout<<"cpu 调度下一个运行的进程。"<

NowTime+=RR;

//依据上面建设的映射按名取出所需运行的时间

int ALLNeedCpu;

for(int i=0;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_CalculateCpuNeed(int*Run_Process_CpuNeed,int count){

Process *temp=head1;

for(int i=0;i

int ALLNeedCpu=temp->NeedCpuTime;