操作系统课程设计报告书Word格式文档下载.docx
《操作系统课程设计报告书Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《操作系统课程设计报告书Word格式文档下载.docx(58页珍藏版)》请在冰豆网上搜索。
intmain(){
cout<
<
"
***********操作系统课程设计程序***********"
endl;
***********by:
蔡鹏程************"
***********学号:
1213072019***********"
intt;
t=0;
while(t!
=4){
***********主界面***********"
1.处理机管理"
2.主存空间的分配与回收"
3.虚存管理"
4.退出程序"
选择你想要的操作:
******************************************"
loop:
cin>
>
t;
Sleep(100);
switch(t)
{
case1:
windows_cpu(t);
break;
case2:
windows_M(t);
case3:
windows_VM(t);
case4:
default:
{
cout<
输入错误请重新输入:
gotoloop;
}
}
}
**************谢谢使用,再见***************"
return0;
2.2.3界面设计思路
本模块代码采用C++常用的switchcase语句进行选择编写,根据用户的选择恰当调用其他模块的函数,用常用函数库的清屏函数和sleep函数对界面进行美化。
2.3处理机管理模块
2.3.1按先来先服务的调度算法实现处理机调度
2.3.1.1算法描述
(1)假定系统中有3-5个进程,每个进程由一个进程控制块(PCB)来表示。
进程控制块的结构如图6所示。
进程控制块包括:
进程名、运行时间、到达时间、进程状态、链接指针组成。
(2)通过队首指针head,用来之处最先进入系统的进程,各就绪进程通过链接指针连在一起。
(3)处理机调度是选择队首指针指向的进程投入运行,在模拟过程中对进程不实际启动运行,只是执行估计运行时间减一,此操作用来模拟进程的一场运行,省去进程的现场保护和先恢复工作。
(4)有简单的显示和打印语句,显示运行的进程名、运行时间等属性。
图6PCB
2.3.1.2算法数据结构以及部分代码解析
1.进程控制块(PCB)
typedefstructpcb//进程控制块
charpname[N];
//进程名
intruntime;
//运行时间
intarrivetime;
//到达时间
charstate;
//进程状态就绪状态:
R完成状态:
C
structpcb*next;
//链接指针指向下一个进程
3.FCFS必要数据和函数清单
PCBhead_input;
//就绪队列
PCBhead_run;
//运行队列
staticcharR='
r'
C='
c'
;
unsignedlongcurrent;
//记录系统当前时间的变量
voidinputprocess();
//建进程的函数
intreadydata();
//就绪队列是否为空
intrunprocess();
//运行进程
intreadyprocess();
//检查队列并准备运行进程的函数
4.运行代码解析
p1=head_run.next;
p2=&
head_run;
while(p1!
=NULL)
p1->
runtime--;
current++;
if(p1->
runtime<
=0)
{
printf("
Timeis%4d;
Process%send.\n"
(current+500)/1000,p1->
pname);
state=C;
p2->
next=p1->
next;
deletep1;
p1=NULL;
本段代码是运行进程时当运行队列队首不为空时进行进程运行,重复给队首进行占用时间片,当队首进程运行时间结束后,将程序从运行队列移出,转为下一个进程。
2.3.1.3算法效果演示
图7FCFS实现
2.3.2按时间片转轮法实现处理机调度
2.3.2.1算法描述以及算法数据结构
1.RR与FCFS代码比较
程序pcb和运行代码与上算法基本相同,代码不同处有2点:
1.FCFS就绪队列不空时,允许进入到运行队列的进程仅能有一个,但RR算法需要全部进入。
2.FCFS运行队列取进程运行后强行占有时间片直至结束,RR算法运行完单位时间片后加指针后移(轮转代码)。
2.装载代码解析
p3=head_input.next;
head_input;
//装载运行队列进程
while(p3!
if(((unsignedlong)p3->
arrivetime<
=current)&
&
(p3->
state==R))//满足条件
printf("
Process%sstart,\n"
(current+500)/1000,p3->
p2->
next=p3->
p3->
p1->
next=p3;
p3=p2;
if(!
is_RR)gotoloop;
//转移指令
}
p2=p3;
p3=p3->
2.3.2.2算法效果演示
图8RR算法实现
2.4主存空间的分配与回收模块
2.4.1首次适应法分配管理链式可变分区
2.4.1.1算法描述
当有进程要求分配主存时,依据首次适应算法从链头开始,沿链查找一个足矣容纳改进程的空闲区,若这个分区比较大,则一分为二,一部分分配给进程,另一部分作为空闲区仍留在链中的当前位置,修改它的上一个空闲区的向前指针值为再加上分配给进程的分区大小,下一个空闲区的向后指针值为再加上分配给进程的分区大小,使链保持完整。
若这个分区的大小正好等于进程大小,该空闲区全部分配给进程,并将该空闲区从链中摘除。
再在已分配表中找一个空目录,登记刚刚分配的内存始址、长度和进程号。
2.4.1.2算法数据结构以及部分代码解析
1.算法数据结构
structmemory
{
structmemory*former;
//前向指针
intaddress;
//地址
intnum;
//作业号
intsize;
//分配内存大小
intstate;
//状态0表示空闲1表示已分配
structmemory*next;
//后向指针
};
2.必要数据和函数清单
typedefstructmemoryMEMORY;
MEMORY*mem;
constintsize_min=10;
//内存允许的最小空闲块的大小
boolis_optimist;
//判断是否是最佳适应算法
voidinit();
//初始化内存块
voidexec();
//执行相应算法
voidF_F(int);
//依次初始化每个作业,并根据相应算法对作业分配内存
voidalloc(MEMORY*,MEMORY*);
//分配内存算法(包括两种不同算法)
voidfree(MEMORY*,int);
//首次适应算法回收内存
voidfree_optimist(MEMORY*,int);
//最佳适应算法回收内存
voidsort(MEMORY*);
//对内存链进行排序
voidinsert(MEMORY*,MEMORY*);
//按空间大小将作业顺序插入到内存链
voidprint(MEMORY*);
//打印内存链
3.内存分配代码
用户在输入作业号后对将要运行的进程的属性进行输入,传输到alloc函数中进行分配判断
Ptr表示内存空间assign表示用户输入进程相关属性
voidalloc(MEMORY*ptr,MEMORY*assign)
{//根据算法分配内存(is_optimist状态)
if(ptr->
next==NULL)
{//内存没有作业运行
size>
=assign->
size)
{//内存空间大于作业所需空间,为内存分配空间
ptr->
size=ptr->
size-assign->
size;
assign->
state=1;
next=assign;
former=ptr;
cout<
作业"
(assign->
num)<
申请"
size)<
"
k的内存空间"
}
else
{
没有足够的内存空间为作业"
分配"
deleteassign;
else
{//内存中如果已经分配了空间
MEMORY*previous,*current;
previous=ptr;
//previous为链表中的第一个元素
current=previous->
while(current!
=NULL)
{//当前区间不为空(最后一个区间的next为空),即没有循环到最后
//如果当前内存空间大于作业所需空间并且内存没有被分配
//则结束循环,当前current位置即为要插入的位置
if(current->
size&
current->
state==0)
break;
previous=current;
//previous后移
current=current->
if(current==NULL)
{//空闲链中没有为作业分配所需的空间,即释放的空闲区间小于要分配的作业空间
//不够用,则在所有作业后边另外再申请空闲区,如作业4
{//内存中还有足够没分配的空闲空间为此作业分配
//此时ptr指向内存上未分配空闲空间的起始地址
address=640-(ptr->
size);
former=previous;
previous->
{//释放的空闲链中有可为此作业分配的空间
if((current->
=size_min)
{//空闲链所具备的空间与作业所需空间大小差不多时
//直接把整个空闲块的空间分配给作业否则从空闲块中
current->
num=assign->
num;
//划出与作业等同的空间
(current->
k的内存间"
{//从空闲块中划分一块与作业大小等同的空间
size=current->
address=current->
address+current->
{//此要分配的空间是空闲链的最后一个元素
former=current;
next=current->
(current->
next)->
former=assign;
}}
2.4.1.3算法效果演示
1.申请内存
申请空间:
1——130KB2——60KB3——100KB
图9申请空间1
图10申请空间2
图11申请空间3
2.释放内存
释放内存:
释放1
图12释放1号作业
2.4.2最佳适应法分配管理链式可变分区
2.4.2.1算法描述
采用最佳适应算法实现内存的分配与回收的实现原理以及使用的数据结构和首次适应算法类似。
所不同的是,分配时,总是分配与进程大小最接近的一个分区。
为此,可将空闲区按照大小,从小到大排列。
2.4.2.2算法数据结构以及部分代码解析
1.最佳适应算法与首次适应算法的比较
最佳适应算法的数据结构和必要的函数清单已在上显示,最佳适应算法在作业申请内存时,需要对可变分区大小进行排序,进而选取内存块最小的分区进行分配,这样在回收时,就显的异常麻烦,而首次适应算法则是对分区地址的顺序存取,按照分区地址的大小排序来进行内存的分配和管理
2.分区大小排序代码
voidsort(MEMORY*ptr)
{//排序函数
MEMORY*temp=newMEMORY;
temp->
next=0;
former=0;
while(ptr->
next)
if((ptr->
next==NULL)
{//内存链中只有两个元素
MEMORY*p;
p=ptr->
next=NULL;
insert(temp,p);
//从小到大插入排序
{//内存链中有多个元素
p->
next=p->
(p->
//temp为已经排好的作业队列
next=temp->
(temp->
deletetemp;
2.4.2.3算法效果演示
在内存空间如图12的情况下进行分配:
作业4——120K
图12
图13申请空间
释放作业2和4
图14释放作业2
图15释放作业4
2.5虚存管理模块
2.5.1采用FIFO算法实现分页管理的缺页调度
2.5.1.1算法描述
采用先进先出算法时,用一个数组表示先进先出队列,数组中的各个元素表示进程在主存的页号,假定块数不变,当队列有空余块时,将进程页号装载进数组中;
当队列满需要淘汰是,淘汰最先进入主存的一页
2.5.1.2算法数据结构以及部分代码解析
1.页号以及作业(进程)
structpage{//页面
intjobnum;
//页块中作业号
intstage;
//等级
structjob{
//作业号
intchgnum;
//交换的作业号
page*table;
job*user;
boolis_LRU;
//is_FIFOoris_LRU
voidsetpage(pagetable[],intn);
//页面初始化
voidupstage(pagetable[],intn);
//更新等级
voidsetjob(jobuser[],intn);
//user用户作业初始化
voidrun(pagetable[],jobuser[],intm,intn);
//运行
voidprint(job[]);
//打印函数
3.代码分析
以下代码为作业进入时是否淘汰的判断,与LRU不同的是,当命中时页块不需要刷新操作。
for(inti=0;
i<
m;
i++)//job循环
for(intj=0;
j<
n;
j++)//table是否命中
{
if(table[j].jobnum==user[i].jobnum)//当命中时退出
gotoloop2;
//转入下一个作业
//未命中
for(j=0;
j++)//是否有未分配块
if(table[j].stage==-1)//等级为-1表示未分配
{
table[j].jobnum=user[i].jobnum;
//改名
upstage(table,n);
//更新页表
table[j].stage=0;
//将此块等级改为0,最新
user[i].chgnum=0;
//0表示由新装入
}
}//无分配块且未命中
j++)//找等级为n-1的页块
{
if(table[j].stage==n-1)
user[i].chgnum=table[j].jobnum;
//淘汰页表
table[j].jobnum=user[i].jobnum;
//更换页表
upstage(table,n);
table[j].stage=0;
//更改等级
gotoloop2;
}
}//forj2
loop2:
2.5.1.3算法效果演示
注:
例题采用《操作系统教程第4版》第四章存储管理课后习题第1题3页框(LRU同)
图16FIFO
2.5.2采用LRU算法实现分页管理的缺页调度
2.5.2.1算法描述
采用LRU算法时,用一个数组表示先进先出队列,数组中的各个元素表示进程在主存的页号,假定块数不变,当队列有空余块时,将进程页号装载进数组中;
当队列满需要淘汰是,淘汰最少使用的一页;
当访问的页号与队列中的页号相等时,则进行队列页号等级刷新。
2.5.2.2算法数据结构以及部分代码解析
1.LRU与FIFO的比较
与FIFO不同的是,当命中时页块需要刷新命中块,并且更新其他页框。
2.代码分析
以下代码为作业进入时是否淘汰的判断
for(intj=0;
//刷新命中页块等级
gotoloop1;
}//未命中
if(table[j].stage==-1)//有未分配
//0表示新装入
gotoloop1;
//转入下一个作业
intmax=table[0].stage;
intindex=0;
for(j=1;
j++)//寻找表中等级最大的,即存在最久的淘汰
if(max<
table[j].stage)
{max=tabl