操作系统课程设计总结报告.docx

上传人:b****5 文档编号:6410505 上传时间:2023-01-06 格式:DOCX 页数:41 大小:554.16KB
下载 相关 举报
操作系统课程设计总结报告.docx_第1页
第1页 / 共41页
操作系统课程设计总结报告.docx_第2页
第2页 / 共41页
操作系统课程设计总结报告.docx_第3页
第3页 / 共41页
操作系统课程设计总结报告.docx_第4页
第4页 / 共41页
操作系统课程设计总结报告.docx_第5页
第5页 / 共41页
点击查看更多>>
下载资源
资源描述

操作系统课程设计总结报告.docx

《操作系统课程设计总结报告.docx》由会员分享,可在线阅读,更多相关《操作系统课程设计总结报告.docx(41页珍藏版)》请在冰豆网上搜索。

操作系统课程设计总结报告.docx

操作系统课程设计总结报告

《操作系统课程设计》

总结报告

 

学期2012-2013学年第二学期

学院软件学院

学号20113311

姓名杜常数

2013年6月28日

本学期开设了操作系统课程,为了更好的理解操作系统理论,掌握其应用,特设此操作系统实验课程,在该操作系统实验中包括进程管理、存储管理、设备管理和文件管理四个实验部分。

一、进程控制

1.1目的

利用简单的结构和控制方法模拟进程结构、进程状态和进程控制。

1.2内容

用PCB表示整个进程实体,利用键盘控制方法模拟进程执行中产生的事件。

具体过程:

1、定义PCB(可以采用静态结构或动态结构):

包括理论PCB中的基本内容,如内部ID、外部ID、进程状态、队列指针。

由于无法实现真正的进程创建功能,在实验中只需建立PCB,用它代表完整的进程。

2、定义进程状态转换方式:

进程的状态转换是由进程内部操作或操作系统的控制引起,由于无法实现这些功能,学生可以采用随机数方法或键盘控制方法模拟,并实现对应的控制程序。

随机方法指产生1-6的随机数,分别代表创建进程(c)、结束进程(e)、进程阻塞(b)、激活进程(w)、调度进程(p)、时间片到(t)等事件;键盘模拟方法指定义6种按键代表以上6种事件。

3、根据四种事件处理就绪队列、阻塞队列和当前执行中的进程。

每次事件处理后应形象地显示出当前系统中的执行进程是哪一个,就绪队列和阻塞队列分别包含哪些进程。

1.3数据结构

为了使程序能独立运行,需要为每个进程设置模拟PCB(ProcessControlBlock)进程控制块方便于创建进程和撤销进程。

具体PCB的结构定义如下所示:

typedefstructprocess{

charname[20];

intstart;

intsize;

structprocess*next;

}process;

其中name[20]用来存储进程的名;start为int型存储进程的起始地址;size为进程块的大小;next指针指向下一个进程控制块。

1.4算法设计及流程图

主函数:

主要功能是通过输入的命令行,来调用其他函数,共同完成系统的功能,利用analysisStr(charstr[],char&commond,charch1[],charch2[]),commond为引用传递,通过commond返回其要做的操作。

并通过switch分别开来。

主函数的流程图如下所示:

图1.1

创建进程Creat函数:

通过该函数来创建进程,在该函数开始设置f为false,中先对free链表每一个节点与所需要创建进程的大小进行比较,如果找到大于等于所需的节点则设置f为true,并找到其中大于等于所需内存块中最小的一个节点。

如果检查完毕f为false说明没有找到相应的内存块,返回FAIL否则用得到的节点减去所需大小,如果差值小于5则将该部分内存块全部分配出去,以减少内存碎片。

实现如下所示:

intcreat(process*&ready,process*&free,charch1[],intsize)//参数ch1进程名;ch2为大小

{

process*p,*q,*r;

intprosize=size,minsize;

boolf=false;

//cout<

p=free;

while(p!

=NULL){

if(p->size>=prosize){

if(f==false){

f=true;

minsize=p->size-prosize;

}

elseif(minsize>(p->size-prosize))

minsize=p->size-prosize;

}

p=p->next;

}

if(f==false)//没有找到比prosize大的块

returnFAIL;

p=free;

q=p;

while(p->size-prosize!

=minsize){

q=p;

p=p->next;

}

if(minsize<=5){//剩余较小时freeqp

if(p==q)

free=NULL;

else

q->next=p->next;

p->next=ready;

ready=p;

strcpy(p->name,ch1);

}

else{

r=(process*)malloc(sizeof(process));

r->size=prosize;

r->start=p->start;

p->start=p->start+prosize;

p->size-=prosize;

r->next=ready;

ready=r;

strcpy(r->name,ch1);

}

returnOK;

}

阻塞进程block_process函数:

由于执行队列当中只有一个进程,只需将该executing(执行队列)的头结点移动到block(阻塞队列)里即可

实现如下所示

intblock_process(process*&executing,process*&block)

{

executing->next=block;

block=executing;

executing=NULL;

returnOK;

}

时间片到timeOut函数:

时间片到,只需将执行队列executing里的结点放入就绪ready队列里即可,同时设置executing为NULL在主函数里再对ready进行调度,将下一个进程放入执行队列里。

实现如下所示:

voidtimeOut(process*&ready,process*&executing)

{

if(ready==NULL)

return;

executing->next=ready;

ready=executing;

executing=NULL;

}

1.5小结

对于链表中的操作还有很多地方需要提高,例如在creat函数中,曾经出现了创建进程时出现free链表中的数据丢失。

因此在编程时做到理论正确的前提下还应该注意多进行数据的测试,保证程序里的bug减少到最低,提高容错性能。

二、请求分页存储器管理

2.1目的

实现分页式存储地址转换过程,在此基础上实现请求分页的地址转换。

实现请求页式地址转换中出现的缺页现象时,用到的先进先出FIFO、最近最久未使用LRU、最佳OPT置换算法。

2.2内容

利用键盘输入本模拟系统的物理块的大小,作业的页表中的块号;完成逻辑地址转换成相应的物理地址的过程。

1、建立一张位示图,用来模拟内存的分配情况,利用随机数产生一组0和1的数对应内存的使用情况。

2、输入块(页)的大小,通过模拟位示图为本作业分配内存空间建立相应的页表(长度不定);

3、录入逻辑地址转换成相应的物理地址

4、扩充页表,变成请求式的二维页表(增加存在位等)完成地址转换。

5、输入分配给本作业的块数,模拟作业执行的逻辑地址转换成页面调度次序;

6、分别采用OPT、FIFO、LRU置换算法,利用堆栈结构完成页面置换;记录被换出的页面和新换入的页面。

2.3数据结构

结构体包含Stack和pagetable。

Stack主要用来模拟内存sign表示是否使用,而pageNum表示页号。

Pagetable用来模拟页表通过查找内存中的pageNum获取页号。

Stack{

intsign;

intpageNum;

structstack*next;

}

pagetable{

intmemory_block;

intsign;

}pagetable;

包含四个类,分别是基类PageReplace类,和由PageReplace派生出的先进先出FIFO类,最近最久未使用LRU类,最佳置换算法OPT类。

Stack,pagetable与各个类之间的关系和类的属性操作可通过下面类图显示出来:

图2.1页面置换算法类图

类PageReplace保护成员变量page:

页表,memory:

可用内存块,page_size:

页的大小,memory_num:

可用的内存块数,table_size:

页表的长度,用char类型的数组作为位示图,hit记录命中次数,all表示所有访问次数;

公有成员:

intget_byte(introw,intcol)获取位示图当中第row行,第col列的值

voidset_byte(introw,intcol,vaule)设置位示图中第row行,第col列的值为vaule(1或0)

voidset_byte(intnum,intvalue)设置位示图中第num块的值为vaule

利用构造函数初始化page,memory,page_size,memory_num,table_size,hit,all位示图等;

IntgetFreeNum()获取空闲的内存块号,没有空闲则返回-1

对于FIFO,LRU,OPT类,除了继承自PageReplace的函数之外还新加一个intgetPhysical(intaddress)传递进来一个地址,返回相应的物理地址的函数

2.4算法设计及流程图

主函数:

主函数需要把以上定义的三个类三个类联系组合起来,共同完成该实验的各种置换算法,达到演示目的。

开始时各个类里面的各个必要属性如页表长度,可用内存块数,内存块的大小等还不知道,因此在该函数首先需要对系统进行初始化。

输入完成之后分别调用fifo和lru的show_byte()函数,显示其内存块的使用情况。

同时OPT算法中需要知道每次调用时使用的逻辑,因此需要设定一个int型的数组保存每次调用时没有越界的逻辑地址。

然后用循环对输入的命令行进行分析后,根据命令类型选择相应的操作。

主要包括显示位示图,显示帮助,通过g命令调度逻辑地址为address并分别显示fifo算法结果和lru算法的结果,退出命令q(退出循环)等等。

当退出循环时,则根据保存的逻辑地址依次地调用opt算法查看运算结果。

主函数的流程图如下所示

图2.2

getPhysical(address):

调入内存页同时返回物理地址。

流程图如下所示

图2.3

其中replace()为虚函数,用来确定具体换出哪一页,是各个置换算法的具体不同之处,由PageReplace类继承过来的子类来实现。

对先进先出来说只需将内存中的数据依次后移,再将调入页信息装入链的头结点即可;最近最久未使用算法中由于对每次命中的页都提到最前面因此最后一个结点便是最近最久未使用的一个,只需把该结点提到链表头结点处,再将数据装入队受即可。

对于最佳置换算法则相对复杂一些,由类图可以看到有一个getOPTNum()即为获取最近一段时间内不会被调用的页号,再由该页号来确定置换哪一页,getOPTNum()实现如下所示:

intgetOPTNum(){

int*n=newint[memory_num];

inti,j,count;

stack*s=memory;

for(i=0;i

n[i]=s->pageNum;

s=s->next;

}

count=memory_num;

for(i=now+1;i

=1;i++)

for(j=0;j

if(n[j]==(int)add[i]/page_size){

n[j]=-1;

count--;

break;

}

}//for

for(i=0;i

if(n[i]!

=-1){

count=n[i];

break;

}

now++;

returncount;

}

2.5小结

原先对页面置换算法掌握不太好,通过这一次的实验让我对页面置换算法包括调入一页,换出一页等都有了较深的理解。

因此有些时候多深入学习,做些实验也有助于对理论知识的掌握。

三、设备管理

3.1目的

模拟实现包括设备的添加和删除,设备的分配和回收,体现设备分配中的设备独立性。

掌握外围设备的体系结构和管理方法。

3.2内容

方法:

假定模拟系统中有K、M、T和P设备,采用安全分配方式。

实现过程:

1、设备管理子系统涉及到系统设备表(SDT)、通道控制表(CHCT)、控制器控制表(COCT)和设备控制表(DCT)来体现输入输出系统的四级结构和三级控制。

我们模拟这样的数据结构来完成对外围设备的管理。

(1)添加设备:

增加对应的设备控制表和系统设备表中的表项,如果需要新建对应的控制器控制表。

(2)删除设备:

删除对应的设备控制表和系统设备表中的表项,如果需要删除对应的控制器控制表。

2、独占设备的分配与回收,创建进程申请独立设备名称,建立起连接通路或阻塞到设备、控制器或通道上面,等待其他归还设备的进程后唤醒;

3、申请设备时,可以通过申请某一类设备来实现设备独立性,将逻辑设备名映射为物理设备。

3.3数据结构

PCB类:

主要职责是存储进程的,以及它所需要申请的设备的名称DCT

以下是对进程控制块PCB的定义

publicclassPCB{

publicStringname;

publicDCTdct;

publicPCBnext;

publicPCB(Stringstr){

this.name=newString(str);

this.dct=dct;

this.next=null;

}

}

图3.1PCB类图

SDT类:

用于记录系统之中全部的设备情况,主要属性有设备的类型type,设备的名称name,以及由它指向的DCT。

而其他的如ltype,lname,ldct是与java可视化有关的标签对象,这里不再赘述。

主要的属性则为构造函数。

SDT的类图如下图所示:

图3.2SDT类图

DCT类:

用于记录具体某个设备的情况,属性主要有设备的类型type,设备的名称name,设备的状态status以及等待队列的队首指针phead,occupyName用于记录该设备现在被哪一个进程占用,coct用来记录与之对应的设备控制器COCT。

其函数除了必要的构造函数外还有setBusy()当设备忙时应做的相应操作,setFree()当设备被归还时各个属性的值应该做的相应操作。

DCT的类图如下所示:

图3.3DCT类图

COCT类:

用于模拟设备管理当中的控制器控制表。

连接着CHCT(通道控制表)和DCT(设备控制表)。

主要的属性有name控制器名称,status控制器的状态包括忙与闲,occupyName表示占用的进程名称。

其他的如lx,ly,rx,ry等等则是与java可视化有关的内容。

主要的函数包含构造函数COCT(Stringname,intnum,CHCTch)设置空闲setFree(),设置忙setBusy()等。

COCT类的类图如下所示:

图3.3COCT类图

CHCT类:

对应于设备控制管理当中的通道,跟前面的类相似也有对应的通道名称name,状态status,占用的进程名称occupyName,另外还有与之对应的COCT,队首指针pHead等。

下图即为CHCT(通道控制表)类的类图:

图3.4CHCT类图

3.4算法设计及流程图

(1).添加设备:

①在界面文本框中输入要添加的设备名称name,设备类型type以及希望与之相连接的控制器名coname;②点击添加设备按钮,首先查看是否存在名为coname的控制器,若没有则提示出错返回;③否则申请一个结点SDT类型的结点pS,DCT类型的结点pD,并分别加入到系统当中去,如下图所示即为添加设备的流程图:

图3.5添加设备流程图

(2).删除设备:

①输入要删除的设备名称name;②根据名称在SDT表中查找与name相同的设备,若没有查找到,则提示出错返回;③否则检查设备是否正忙,若忙则提示无法删除设备并直接返回;④否则将查找到的结点从链表中删除。

(3).添加控制器:

添加控制器时与添加设备类似,但是需要输入的不太相同,需要输入添加的控制器名称,与之连接的通道名称,其他实现地方大致相同。

(4).删除控制器:

输入要删除的控制器名称后先对所有的控制器进行查找,若没找到则提示出错并退出,否则检查与控制器连接的设备是否已经删除,假如有与控制器连接的设备则提示仍有设备与之连接并返回。

若所有的检查完毕后则将所得到的结点删除即可。

(5).申请设备:

①输入要申请设备进程pname和设备名称sname;

②先对已有的进程检查,是否有与当前进程名称相同的,若有则提示出错并返回;

③再对系统设备表SDT查找与之对应的设备若未找到提示出错返回。

④检查完毕后根据DCT状态status查看该设备是否在忙,若忙便将其PCB插入等待队列里。

若空闲则将该设备分配给该进程,并调用DCT中的setBusy();

⑤申请到设备后找出与之对应的控制器,若控制器忙便将进程PCB挂在该控制器的等待队列上,否则将该控制器分配给该进程并调用COCT中的setBusy()函数;

⑥申请到控制器后再找到与控制器连接的通道,若通道的状态status为忙则将进程的PCB挂在队列上,否则将通道也分配给进程并调用CHCT当中的setBusy()将通道状态设置成忙。

(6).归还设备:

①输入要归还的设备名称,若未能查找到该设备,则提示出错返回即可;②检查设备状态status是否为空闲若是空闲则直接返回,否则进入③;

③检查设备上的进程是否形成DCT-COCT-CHCT的通路,若没有则提示进程I/O请求尚未完成返回;

④若已经形成通路,则依次将DCT,COCT,CHCT上的等待进程调度进来,若等待队列为空则调用对应的setFree()即可。

3.5小结

在做实验的过程当中遇到了各种各样的困难,包括使用java的可视化与链表组织结构等。

而且因为理论知识没有掌握牢固,系统在把设备分配给请求I/O的进程后才能进一步申请控制器和通道,结果我做的实验中进程申请设备时若进程挂在设备上后又检查控制器,通道。

因此以后我先要把理论的知识掌握牢固,再做实验,这样才能减少错误做到事半功倍。

四、文件管理

4.1目的

利用交互式命令实现树型目录结构和文件管理。

4.2内容

(1)实验内容和步骤:

在文件中保存目录内容,创建文件或子目录可以用命令行命令:

MD、CD、RD、MK(创建文件)、DEL(删除文件)和DIR。

目录项包括文件或目录名称、类型(文件、目录或空目录项)、创建日期以及下一个目录项指针、下一级目录项指针。

(2)具体过程:

1、创建初始文件,建立根目录的“.”和“..”目录项。

2、显示命令提示符“$”。

3、输入命令后根据命令含义完成相应文件操作:

●MD:

在目录文件中创建子目录,同时搜索当前目录最后一个目录项,并保存指针信息;

●CD:

根据当前目录切换到指定目录;

●RD:

搜索所要删除的目录是否为空目录,若是则删除;

●MK:

在当前目录中创建文件名称;

●DEL:

搜索所要删除的文件是否存在,若是则删除;

●DIR:

列出当前目录的所有目录项。

4.3数据结构

FCB:

结构体FCB标识文件所在的盘块,实验中每一个盘块的大小为512B,而该结构体里num则标明是哪一块。

图4.1FCB结构体

Disk:

模拟磁盘,Disk结构体中有磁盘名name,FAT表,位示图bsign,磁盘的大小size,磁盘当中空闲的大小free,总共的盘块数blockNum,指针pfnow用于指向当前磁盘的目录,指针root指向磁盘的根目录,指针next指向下一个磁盘的结点。

图4.2即为UML结构体图表示。

图4.2Disk结构体

File结构体:

File是用来存储文件和目录信息的结构体,包含name文件或目录的名称,type用来区分是文件还是目录,其中type=1时表示为目录,type=2表示是文件,time是文件或目录的创建时间,size主要用于记录文件的大小,first指针指向的是FAT表当中的第一个盘块,child用于指向子目录当中的头结点,当为文件时child等于NULL,由于每个目录中都有特殊的目录“.”和“..”,“.”的child直接指向自身,“..”的child指向其父目录。

Next指针指向当前目录的下一个结点。

图4.3Fie结构体

FileManage类:

文件管理类,包括添加一个磁盘函数add_Disk(name,size),以及与系统中的命令相对应的md(name),mk(name,size)等函数。

如图4.4所示:

图4.4FileManage类图

4.4算法设计及流程图

(1)md命令的实现:

①先对输入的文件名进行检查,包括是否允许访问,名称是否为空是否有非法符号等,若有一条不满足则提示错误并返回;

②检查当前的目录中是否已经存在与之相同的目录名若已经存在,则提示错误并返回;

③否则利用指针p新申请一个File结点,type为1,name为输入目录名,调用get_time()给结点time赋值;

④在当前链中顺序插入新结点p;

⑤调用init_catalog(p->child)给结点子目录初始化。

图4.5md命令流程图

(2)cd命令的实现:

对于cd命令只需从命令行中提取出要打开的目录名,对链表中的所有结点遍历查找type为1的与name相同的结点,若找到则置pdnow->pfnow=p->child若找不到显示系统找不到路径即可。

实现的代码如下所示:

voidFileManage:

:

cd(stringname)

{

File*p=pdnow->pfnow;

if(name=="\\"){

pdnow->pfnow=pdnow->root;

return;

}

while(p!

=NULL){

if(ToLower(p->name)==ToLower(name)&&p->type==1)

break;

else

p=p->next;

}

if(p==NULL){

cout<<"系统找不到指定的路径。

\n";

return;

}

else

pdnow->pfnow=p->child;

}

(3)rd命令的实现:

利用命令行中输入的要删除的目录名name,对pdnow->pfnow中结点顺序访问,查找type为1同时名为name的结点,若没有找到提示系统未找到指定路径并返回,若找到则检查结点child中是否为空,若不为空则提示子目录不为空并返回,若为空则将结点删除即可。

该部分实现的函数如下所示:

voidFileManage:

:

rd(std:

:

stringname){

File*p,*p1;

if(name.empty()){

cout<<"语法命令不正确。

\n";

return;

}

if(name=="."||name==".."){

cout

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 能源化工

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1