第一篇:操作系统课程设计完整
操作系统课程设计
湖北民族学院信息工程学院11级计算机专业操作系统课程设计
(操作系统课程设计)
连续动态分区内存
管理模拟实现
学生姓名: 韩 慧 学生学号: 031140312 班 级: 031140--3
031140
1、0
2、0
3、04班制
二〇一三年十二月
1 湖北民族学院信息工程学院11级计算机专业操作系统课程设计
目录
《操作系统》课程设计....................................................... 1 引言......................................................................3 课程设计目的和内容 ...................................................... 3 需求分析.........................................................................3 概要设计...................................................................3 开发环境........................................................................ 4 系统分析设计..................................................................... 4 有关了解内存管理的相关理论.................................................. 4 内存管理概念........................................................................4 内存管理的必要性..............................................................4 内存的物理组织.............................................................4 什么是虚拟内存.................................................................5 连续动态分区内存管理方式................................................... 5 单一连续分配(单个分区)................................................... 5
固定分区存储管理...............................................................5 可变分区存储管理(动态分区).............................................. 5 可重定位分区存储管理........................................................5 问题描述和分析....................................................................6 程序流程图........................................................................6 数据结构体分析..................................................................8 主要程序代码分析...............................................................9 分析并实现四种内存分配算法 ................................................. 11 最先适应算.....................................................................11 下次适应分配算法..........................................................13 最优适应算法...............................................................16 最坏适应算法......................................................... ......18 回收内存算法................................................................20 调试与操作说明.................................................................22
初始界面.......................................................................22 模拟内存分配...............................................................23
已分配分区说明表面............................................................24 空闲区说明表界面.............................................................24 回收内存界面.....................................................................25 重新申请内存界面..........................................................26. 总结与体会...................................................................... 28
2 湖北民族学院信息工程学院11级计算机专业操作系统课程设计
参考文献......................................................................... 28
引言
操作系统是最重要的系统软件,同时也是最活跃的学科之一。我们通过操作系统可以理解计算机系统的资源如何组织,操作系统如何有效地管理这些系统资源,用户如何通过操作系统与计算机系统打交道。
存储器是计算机系统的重要组成部分,近年来,存储器容量虽然一直在不断扩大,但仍不能满足现代软件发展的需要,因此,存储器仍然是一种宝贵而又紧俏的资源。如何对它加以有效的管理,不仅直接影响到存储器的利用率,而且还对系统性能有重大影响。而动态分区分配属于连续分配的一种方式,它至今仍在内存分配方式中占有一席之地。
课程设计目的和内容:
理解内存管理的相关理论,掌握连续动态分区内存管理的理论;通过对实际问题的编程实现,获得实际应用和编程能力。
编写程序实现连续动态分区内存管理方式,该程序管理一块虚拟内存,实现内存分配和回收功能。 分析并实现四种内存分配算法,即最先适应算法,下次最先适应算法,最优适应算法,最坏适应算法。内存分配算法和回收算法的实现。
需求分析
动态分区分配是根据进程的实际需要,动态地为之分配内存空间。在实现动态分区分配时,将涉及到分区分配中所用的数据结构、分区分配算法和分区的分配和回收操作这样三个问题。常用的数据结构有动态分区表和动态分区链。在对数据结构有一定掌握程度的情况下设计合理的数据结构来描述存储空间,实现分区存储管理的内存分配功能,应该选择最合适的适应算法(首次适应算法,最佳适应算法,最后适应算法,最坏适应算法),在动态分区存储管理方式中主要实现内存分配和内存回收算法,在这些存储管理中间必然会有碎片的产生,当碎片产生时,进行碎片的拼接等相关的内容
概要设计
本程序采用机构化模块化的设计方法,共分为四大模块。 ⑴最先适应算法实现
从空闲分区表的第一个表目起查找该表,把最先能够满足要求的空闲区分配给作业,这种方法目的在于减少查找时间。为适应这种算法,空闲分区表(空闲区链)中的空闲分区要按地址由低到高进行排序。该算法优先使用低址部分空闲区,在低址空间造成许多小的空闲区,在高地址空间保留大的空闲区。 ⑵下次适应分配算法实现
3 湖北民族学院信息工程学院11级计算机专业操作系统课程设计
该算法是最先适应算法的变种。在分配内存空间时,不再每次从表头(链首)开始查找,而是从上次找到空闲区的下一个空闲开始查找,直到找到第一个能满足要求的的空闲区为止,并从中划出一块与请求大小相等的内存空间分配给作业。该算法能使内存中的空闲区分布得较均匀。 ⑶最优适应算法实现
它从全部空闲区中找出能满足作业要求的、且大小最小的空闲分区,这种方法能使碎片尽量小。为适应此算法,空闲分区表(空闲区链)中的空闲分区要按从小到大进行排序,自表头开始查找到第一个满足要求的自由分区分配。 ⑷最坏算法实现
最坏适应分配算法要扫描整个空闲分区或链表,总是挑选一个最大的空闲分区分割给作业使用。该算法要求将所有的空闲分区按其容量从大到小的顺序形成一空闲分区链,查找时只要看第一个分区能否满足作业要求。
开发环境:
win7 下 VC++6.0 系统分析设计:
相关算法原理,算法流程图,涉及的数据结构内容都相应包含在各章节中
有关了解内存管理的相关理论
内存管理概念:
内存管理,是指软件运行时对计算机内存资源的分配和使用的技术。其最主要的目的是如何高效,快速的分配,并且在适当的时候释放和回收内存资源。内存不是预先划分好的,而是在系统运行的过程中建立分区.当作业装入主存时,根据作业所需要的主存容量查看是否有足够的主存空间,若有则按需要分割一个分区给该作业;否则令该作业等待.分区长度不固定分区个数不固定。这种存储管理的方法克服了固定分区严重浪费主存的问题,提高了主存资源的利用率。
内存管理的必要性:
内存管理对于编写出高效率的 Windows 程序是非常重要的,这是因为Windows 是多任务系统,它的内存管理和单任务的 DOS 相比有很大的差异。DOS是单任务操作系统,应用程序分配到内存后,如果它不主动释放,系统是不会对它作任何改变的;但 Windows 却不然,它在同一时刻可能有多个应用程序共享内存,有时为了使某个任务更好地执行,Windows 系统可能会对其它任务分配的内存进行移动,甚至删除。因此,我们在 Windows 应用程序中使用内存时,要遵循Windows 内存管理的一些约定,以尽量提高 Windows 内存的利用率。
4 湖北民族学院信息工程学院11级计算机专业操作系统课程设计
1.3 内存的物理组织:
物理地址:
把内存分成若干个大小相等的存储单元,每个存储单元占 8 位,称作字节(byte)。每个单元给一个编号,这个编号称为物理地址(内存地址、绝对地址、实地址)。
二、物理地址空间: 物理地址的集合称为物理地址空间(主存地址空间),它是一个一维空间。
什么是虚拟内存:
虚拟内存是内存管理技术的一个极其实用的创新。它是一段程序(由操作系统调度),持续监控着所有物理内存中的代码段、数据段,并保证他们在运行中的效率以及可靠性,对于每个用户层(user-level)的进程分配一段虚拟内存空间。当进程建立时,不需要在物理内存件之间搬移数据,数据储存于磁盘内的虚拟内存空间,也不需要为该进程去配置主内存空间,只有当该进程被被调用的时候才会被加载到主内存。
连续动态分区内存管理方式的实现
在早期的操作系统中,主存分配广泛采用连续分配方式。 连续分配方式,是指为一个用户程序分配一个连续的内存空间,该连续内存空间指的的是物理内存。下面介绍连续分配的四种方式。
单一连续分配(单个分区)
最简单的存储管理方式,用于多道程序设计技术之前。 内存分为系统区和用户区,系统区由操作系统使用。用户区作为一个连续的分区分配给一个作业。 分区存储管理是满足多道程序设计的最简单的一种存储管理方法,它允许多 4个用户程序同时存在系统内存中,即共享内存空间。 按分区划分方式可分为固定分区和可变分区。
固定分区存储管理
把内存的用户区预先划分成多个分区,每个分区大小可以相同,也可以不同。(分区的划分由计算机的操作员或者由操作系统给出,并给出主存分配表) 分区个数固定,分区的大小固定。 一个分区中可装入一个作业,作业执行过程中不会改变存放区域。 早期的 IBM 的 OS/MFT(具有固定任务数的多道程序系统)采用了这种固定分区的方法。
可变分区存储管理(动态分区)
内存不是预先划分好的,而是在系统运行的过程中建立分区.当作业装入主存时,根据作业所需要的主存容量查看是否有足够的主存空间,若有则按需要分割一个分区给该作业;否则令该作业等待。 分区长度不固定分区个数不固定。 这种存储管理的方法克服了固定分区严重浪费主存的问题,提高了主存资源的利用率。 IBM操作系统OS/MVT采用可变分区存储管理。
5 湖北民族学院信息工程学院11级计算机专业操作系统课程设计
可重定位分区存储管理
解决碎片问题的一种简单方法是采用可重定位分区分配.。 其中心思想是,把不同程序,且在内存中地址不连续的想法让他们连续。
例:内存中现有 3 个空闲区,现有一作业到达,要求获得 30k 内存空间,没有分区满足容量要求,若想把作业装入,可将内存中所有作业进行移动,这样把原来分散的空闲区汇集成一个大的空闲区。 将内存中的作业进行移动使它们连接在一起把原来分散的多个小分区拼接成一个大的空闲区.这个过程称为”紧凑”或”移动”。 需解决的问题:每次”紧凑”后程序或数据装入的物理地址变化采用动态重定位。
问题描述和分析
系统应利用某种分配算法,从空闲分区链表中找到所需大小的分区,如果空闲分区大小大于请求分区大小,则从该分区中按改请求的大小划分出一块内存空间大小划分出一块内存空间分配出去,余下的部分仍留在空闲链表中。然后,将分配区的首址返回给调用者。
当进程运行完毕师范内存时,系统根据回收区的首址,从空闲区中找到相应的插入点,此时可能出现以下四种情况之一:
⑴该空闲区的上下两相邻分区都是空闲区:将三个空闲区合并为一个空闲区。新空闲区的起始地址为上空闲区的起始地址,大小为三个空闲区之和。空闲区合并后,取消可用表或自由链中下空闲区的表目项或链指针,修改上空闲区的对应项。
⑵该空闲区的上相邻区是空闲区:将释放区与上空闲区合并为一个空闲区,其起始地址为上空闲区的起始地址,大小为上空闲区与释放区之和。合并后,修改上空闲区对应的可用表的表目项或自由链指针。
⑶该空闲区的下相邻区是空闲区:将释放区与下空闲区合并,并将释放区的起始地址作为合并区的起始地址。合并区的长度为释放区与下空闲区之和。同理,合并后修改可用表或自由链中相应的表目项或链指针。
⑷两相邻区都不是空闲区:释放区作为一个新空闲可用区插入可用表或自由链。
程序流程图
内存分配流程图,如图
6 湖北民族学院信息工程学院11级计算机专业操作系统课程设计
从头开始查表检索完否?NY返回分区大小>所需大小N继续检索下一个表项Y分区大小-所需大小<=不可再分割大小N从该分区中划出所需大小的新分区Y将该分区从链中移出将该分区分配给请求者修改有关数据结构返回
内存回收流程图,如图
7 湖北民族学院信息工程学院11级计算机专业操作系统课程设计
开始判断空闲区上下内存情况上为空下为空上下都为空上下都不为空将上面的空闲区合并,并回收将下面的空闲区合并,并回收将上下的空闲区合并,并回收直接将其回收结束 数据结构体分析
⑴进程属性结构体 typedef struct readyque { char name[10]; int size; }readyque,*readyqueue; ⑵空闲链表结构体 typedef struct idlyspace { int from; int size; idlyspace * next; }idlyspace,*idly; ⑶已分配链表结构体 typedef struct busyspace { int from; readyque r;
8 湖北民族学院信息工程学院11级计算机专业操作系统课程设计
busyspace * next; }busyspace,*busy
主要程序代码分析
⑴主函数//代码请添加适当的注释。 int main() { Is=(idly)malloc(sizeof(idlyspace)); Is->from=0; Is->size=256; Is->next=NULL; Is2=Is; Bs=(busy)malloc(sizeof(busyspace)); Bs->next=NULL; int t,t1; printf(" .......................欢迎来到动态分区存储管理系统.................. "); printf("...........................请选择要执行的算法:........................... "); printf("......................... 1.最先适应算法
............................... "); printf("......................... 2.下次适应算法 ............................ "); printf("..........................3.最优适应算法
............................... "); printf("......................... 4.最坏适应算法 ................................ "); printf("........................................................................ "); printf("请输入您的选择:"); scanf("%d",&t); int i; while(i!=5) {
printf("........................................................................ ");
printf(".........................操作菜单如下:(请选择).......................n");
printf("..........................1.输入进程分配空间 ...........................n");
printf("......................... 2.进程撤销回收空间 ........................... ");
printf("......................... 3.输出所有空闲分区
.......................... ");
printf("..........................4.输出所有已分配分区.......................... ");
printf(".......................... 5.退
出 .......................... ");
printf("........................................................................ ");
scanf("%d",&i);
switch(i)
{
case 1:
switch(t)
{
case 1:
t1=FF();
9 湖北民族学院信息工程学院11级计算机专业操作系统课程设计
break;
case 2:
t1=NF();
break;
case 3:
t1=BF();
break;
case 4:
t1=WF();
break;
default:
printf("选择算法错误 ");
return 1;
}
if(t1)
printf("分配空间成功 ");
else
printf("分配空间失败 ");
break;
case 2:
t1=recover();
if(t1)
printf("回收成功 ");
else
printf("回收失败 ");
break;
case 3:
Isprint();
break;
case 4:
Bsprint();
break;
} } return 0; }
第三章 :分析并实现四种内存分配算法
最先适应算法
空闲区按地址从小到大的次序排列。
分配:当进程申请大小为 SIZE 的内存时,系统顺序查找空闲区表(链),直到找到容量满足要求(≥SIZE)的空闲区为止。从该空闲区中划出大小为 SIZE的分区分配给进程,余下的部分仍作为一个空闲区,但要修改其首址和大小。
10 湖北民族学院信息工程学院11级计算机专业操作系统课程设计
优点:这种算法是尽可能地利用低地址部分的空闲区,而尽量地保证高地址 6部分的大空闲区,有利于大作业的装入。
缺点:主存低地址和高地址分区利用不均衡。在低地址部分集中了许多非常小的空闲区碎片降低了主存的利用率。 最先适应算法 int FF() { int t=0; readyque D; printf“"请输入进程名:”"); scanf“"%”",D.name);
printf“"输入进程申请空间大小:”"); scanf“"%”",&D.size);
idly l=Is; int mt=256; busy b=Bs; idly min=NULL; while(l)
//寻找空闲表中大小满足申请进程所需大小并且起址最小的空闲结点
{
if(D.size<=l->size)
{
if(l->from
{ mt=l->from; min=l; t=1;
}
}
l=l->next; } if(mt!=256)
{
busy j;
j=(busy)malloc(sizeof(busyspace));
//如果找到则为进程分配空间
11 湖北民族学院信息工程学院11级计算机专业操作系统课程设计
j->from=min->from;
for(int i=0;i<10;i++)
{
j->r.name[i]=D.name[i];
}
j->r.size=D.size;
while(b->next)
{ if(b->next->fromfrom)
b=b->next; else
break;
}
j->next=b->next;
b->next=j;
min->from=min->from+D.size;
min->size=min->size-D.size; } return t; }
下次适应分配算法
最先适应算法的变种。
总是从空闲区上次扫描结束处顺序查找空闲区表(链),直到找到第一个满足容量要求的空闲区为止,分割一部分给作业,剩余部分仍作为空闲区。 下次适应分配算法 int NF() { int t=0; readyque D; printf“"请输入进程名:”"); scanf“"%”",D.name);
12 湖北民族学院信息工程学院11级计算机专业操作系统课程设计
printf“"输入进程申请空间大小:”"); scanf“"%”",&D.size);
int mt=256; idly l=Is2; idly min=NULL; busy b=Bs; while(l) //寻找空闲表中大小满足申请进程所需大小并且起址最小的空闲结点
{
if(D.size<=l->size)
{
if(l->from
{ mt=l->from; min=l; t=1;
}
}
l=l->next; } if(mt!=256)
{
busy j;
j=(busy)malloc(sizeof(busyspace));
j->from=min->from;
for(int i=0;i<10;i++)
{
j->r.name[i]=D.name[i];
}
j->r.size=D.size;
while(b->next)
{ if(b->next->fromfrom)
b=b->next; else
break;
//如果找到则为进程分配空间
13 湖北民族学院信息工程学院11级计算机专业操作系统课程设计
}
//将申请空间进程插入到已分配链表中
j->next=b->next;
b->next=j;
//修改相应空闲节点的起址和大小
min->from=min->from+D.size;
min->size=min->size-D.size;
Is2=min->next;
结点
t=1;
return t; }
l=Is;//l指向空闲表的头
while(l!=Is2)
{
if(D.size<=l->size)
{
if(l->from
{ mt=l->from; min=l; t=1;
}
}
l=l->next; } if(mt!=256) {
busy j;
j=(busy)malloc(sizeof(busyspace));
j->from=min->from;
for(int i=0;i<10;i++)
{
//ls2指向修改结点的下一个
//循环查找
14 湖北民族学院信息工程学院11级计算机专业操作系统课程设计
j->r.name[i]=D.name[i];
}
j->r.size=D.size;
while(b->next)
{ if(b->next->fromfrom)
b=b->next; else
break;
}
j->next=b->next;
b->next=j;
min->from=min->from+D.size;
min->size=min->size-D.size;
Is2=min->next;
t=1;
return t; } return t; }
最优适应算法
空闲区按容量递增的次序排列。
分配:当进程申请存储空间,系统顺序查找空闲区表(链),直到找到第一个满足容量要求的空闲区为止。 采用最优适应算法选中的空闲区是满足容量要求的最小空闲区。 优点:选中的空闲区是满足容量要求的最小空闲区,而不致于毁掉较大的空闲区。
缺点:空闲区的大小一般与申请分区大小不相等,因此将其一分为二,留下来的空闲区一般情况下是很小的,以致无法使用。随着时间的推移,系统中的小空闲区会越来越多,从而造成存储空间的浪费。 最优适应算法 int BF() { int t=0;
15 湖北民族学院信息工程学院11级计算机专业操作系统课程设计
readyque D; printf“"请输入进程名:”"); scanf“"%”",D.name);
printf“"输入进程申请空间大小:”"); scanf“"%”",&D.size);
idly l=Is; idly min=NULL; int mt=256; busy b=Bs; while(l) //在空闲链中寻找第一个大于所输入的进程大小的空闲块
{
if(D.size<=l->size)
{
if(l->size
{
mt=l->size; min=l; t=1;
}
}
l=l->next; } if(mt!=256)
{
busy j;
j=(busy)malloc(sizeof(busyspace)); 空间
j->from=min->from;
//申请分配用于存放进程的内存
//找到第一个满足要求的空闲块
//将第一个满足要求的空闲块(min)的首地址赋给j
for(int i=0;i<10;i++)
{
j->r.name[i]=D.name[i]; 16 湖北民族学院信息工程学院11级计算机专业操作系统课程设计
}
j->r.size=D.size;
while(b->next)
//按从小到大的顺序查找新进程在已分配区中的位置
{ if(b->next->fromfrom)
b=b->next; else
break;
}
j->next=b->next;
b->next=j;
min->from=min->from+D.size;
min->size=min->size-D.size;
} return t; }
最坏适应算法
为了克服最佳适应算法把空闲区切割得太小的缺点,人们提出了一种最坏适应算法,即每次分配时,总是将最大的空闲区切去一部分分配给请求者,剩余的部分仍是一个较大的空闲区。避免了空闲区越分越小的问题。 要求空闲区按容量递减的顺序排列。
分配:进程申请存储区时,检查空闲区表(链)的第一个空闲区的大小是否满足要求,若不满足则令进程等待;若满足则从该空闲区中分配一部分存储区给用户,剩下的部分仍作为空闲区。 最坏适应算法 int WF() { int t=0; readyque D; printf“"请输入进程名:”"); scanf“"%”",D.name);
printf“"输入进程申请空间大小:”");
//将所输入的进程插入进程链
//改变该空闲块的起始地址 //改变该空闲块的剩余大小 湖北民族学院信息工程学院11级计算机专业操作系统课程设计
scanf“"%”",&D.size);
//输入进程申请的空间大小
idly l=Is;//l指向空闲链表ls头
idly min=NULL; int mt=0; busy b=Bs;
//b指向已分配链表Bs头
//找到空闲分区中大小满足进程的请求且尺寸最大的结点
while(l) {
if(D.size<=l->size) //判断进程所申请的大小是否小于空闲区的各结点大小
{
if(l->size>mt)
{ mt=l->size; min=l;//min指向空闲区中尺寸最大的结点
t=1;
}
}
l=l->next; } if(mt!=0) 点
{
busy j;
j=(busy)malloc(sizeof(busyspace));
j->from=min->from;
for(int i=0;i<10;i++)
{
j->r.name[i]=D.name[i];
}
j->r.size=D.size;
//判断是否找到了空闲区的满足结
//l指向空闲链表下一个结点
18 湖北民族学院信息工程学院11级计算机专业操作系统课程设计
while(b->next) 置
//寻找插入到已分配链表中的位
{ if(b->next->fromfrom)
b=b->next; else
break;
}
//把此进程结点j插入到已分配链表中
j->next=b->next;
b->next=j;
//修改空闲链表的相应结点的参数
min->from=min->from+D.size;
min->size=min->size-D.size; } return t; }
可变分区的回收
当某个进程释放某存储区时,系统首先检查释放区是否与系统中的空闲区相邻若相邻则把释放区合并到相邻的空闲区去,否则把释放区作为一个空闲区插入到空闲表的适当位置。
释放区与空闲区相邻的四种情况。
(1) 释放区与前空闲区相邻:把释放区与前空闲区合并到一个空闲区。其首址仍为前空闲区首址,大小为释放区大小与空闲区大小之和。
(2) 释放区与后空闲区相邻:则把释放区合并到后空闲区,其首地址为释放区首地址,大小为二者之和。
(3) 释放区与前后两空闲区相邻:这三个区合为一个空闲区,首地址为前空闲区首址,大小为这三个空闲区之和,并取消后空闲区表目。
(4) 释放区不与任何空闲区相邻:将释放区作为一个空闲区,将其大小和首址插入到空闲区表的适当位置。
19 湖北民族学院信息工程学院11级计算机专业操作系统课程设计
回收内存算法
int recover() { readyque D; printf“"请输入想要回收的进程名”");
scanf“"%”",D.name);
busy b=Bs; idly l=Is; while(b->next) 链表中
{
bool yo=1;
for(int i=0;i<10;i++)
{
if(b->next->r.name[i]==D.name[i]) yo=yo*1;
else yo=0;
}
//如果在已分配链表中则释放该结点所占空间
if(yo)
{
int t=b->next->from;
int ts=b->next->r.size;
//查找输入的进程名是否在已分配湖北民族学院信息工程学院11级计算机专业操作系统课程设计
while(l)
{ if(l->from>t+ts) 不邻接
{ idly tl; tl=(idly)malloc(sizeof(idlyspace)); tl->from=t; tl->size=ts; tl->next=l; Is=tl; break; } if(l->from==t+ts)
l->from=t;
l->size=l->size+ts;
busy tb=b->next;
b->next=b->next->next;
free(tb);
return 1; }
if(l->from+l->size
idly tl;
tl=(idly)malloc(sizeof(idlyspace));
tl->from=t;
tl->size=ts;
tl->next=l->next;
l->next=tl;
break; }
else if(l->from+l->size==t)
//所回收进程与空闲结点上邻接 {
//所回收进程与空闲结点上下都不邻接
//所回收进程与空闲结点下邻接 {
//所回收进程与空闲结点上下都 21 湖北民族学院信息工程学院11级计算机专业操作系统课程设计
l->size=l->size+ts;
if(l->from+l->size==l->next->from) 接
{
l->size=l->size+l->next->size;
idly tm=l->next;
l->next=l->next->next;
freI);
}
br
l=l->next;
}
//从已分配链表中释放所回收进程
busy tb=b->next;
b->next=b->next->next;
free(tb);
return 1;
}
b=b->next; } printf("没找到这”进程 "); return 0; }
//所回收进程与空闲结点上下都邻调试与操作说明
初始界面
程序初始界面,有四个块选择,选择要执行的算法,调试以最坏算法为例,如图
22 湖北民族学院信息工程学院11级计算机专业操作系统课程设计
选择最坏适应算法,如图
模拟内存分配
给进程a分配内存20,如图
23 湖北民族学院信息工程学院11级计算机专业操作系统课程设计
已分配分区说明表界面
同理,给进程b分配内存30,给进程c分配内存40,给进程d分配50,给进程e分配60,如图
空闲分区说明表界面
24 湖北民族学院信息工程学院11级计算机专业操作系统课程设计
查看空闲分区,如图
回收内存界面
回收进程b和d所占内存,如图
已分配分区说明表和空闲分区说明表 如图
25 湖北民族学院信息工程学院11级计算机专业操作系统课程设计
重新申请内存界面
再为新进程i分配内存30,如图
26 湖北民族学院信息工程学院11级计算机专业操作系统课程设计
根据最坏适应算法结合图所示可知,该算法将会从空闲分区表中选择一块最大的内存空间分配给进程i,从图也可看出该模拟算法实现了最坏适应算法
27 湖北民族学院信息工程学院11级计算机专业操作系统课程设计
总结与体会
本次做的课题是动态分区分配算法实现,此次课程设计成功实现了内存分配和内存回收,内存分配中包含了四种算法,分别是首次适应算法,循环首次适应算法,最佳适应算法和最坏适应算法。经编码调试,表明该程序模块是有效可行的。
通过这门课程的学习让我充分了解了内存管理的机制实现,从而更深一步的的对计算机
有了很多了解,这对于以后我们的研究和学习计算机系统起到了很重要的作用。
对于本次论文制作,自己的编程能力有所提高,对操作系统内存分配,存储空间的回收都有全新的认识。
在这次操作系统课程设计中,我使用了c++编写系统软件,对os中可变分区存储管理有了深刻的理解,但是过程中遇到了很多困难,一边做一边学,对c++有了比较多的理解。
实验中遇到很多问题,浪费了很多时间,总而言之是自己学习还不够好,不扎实,希望在以后学习中加以改善,学到更多知识。
参考文献
【1】 汤子瀛,哲凤屏,汤小丹.计算机操作系统.西安:西安电子科技大学出版社,2001.。
28 湖北民族学院信息工程学院11级计算机专业操作系统课程设计
【2】 任爱华.操作系统实用教程.北京:清华大学出版社,2001。
29
第二篇:操作系统课程设计题目
辽宁科技大学操作系统课程设计指导书
一、课程设计目的和要求
本设计是专业基础课《操作系统》的课程设计。由于操作系统课的学时有限,安排实验的次数不多。为了进一步巩固实验成果,加强理论联系实际、分析问题、解决问题的能力,加深对操作系统的基本概念、原理、技术和方法的理解,特安排此次课程设计。它是操作系统课程的实践环节。由于具体的操作系统相当复杂,在短短的一周之内,不可能对所有管理系统进行详细地分析。因此,选择了操作系统中最重要的管理之一进程管理(或进程的死锁、页面置换算法)作为本设计的任务。另外,通过此次设计使学生在使用系统调用的同时,进一步了解系统内部是如何实现系统调用的全过程,使学生在更深层次上对操作系统有所了解。 要求:
1.在具有自主版权的Linux环境下,用c或c++语言,以及相关的系统调用,编程实现进程的创建、控制、软中断通信、管道通信等功能。 2.利用某种高级语言编程实现银行家算法。
3.常用的页面置换算法有:最佳置换算法(Optimal)、先进先出法(Fisrt In First Out)、、最近最久未使用(Least Recently Used),至少实现其中的两种算法。
二、课程设计内容
设计题目1:进程管理及理解 (1)进程的创建
编写一段程序,使用系统调用fork()创建两个子进程。当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示“a”;子进程分别显示字符“b”和“c”。试观察记录屏幕上的显示结果,并分析原因。
(2)进程的控制
修改已编写的程序,将每个进程输出一个字符改为每个进程输出一句话,再观察程序执行时屏幕上出现的现象,并分析原因。
如果在程序中使用系统调用lockf(),来给每一个进程加锁,可以实现进程之间的互斥,观察并分析出现的现象。
(3)①编制一段程序,使其实现进程的软中断通信。
要求:使用系统调用fork()创建两个子进程,再用系统调用signal()让父进程捕捉键盘上来的中断信号;当捕捉到中断信号后,父进程用系统调用kill()向两个子进程发出信号,子进程捕捉到信号后分别输出下列信息后终止:
Child Process11 is Killed by Parent! Child Process12 is Killed by Parent!
父进程等待两个子进程终止后,输出如下的信息后终止: Parent Process is Killed!
②在上面的程序中增加系统调用signal(SIGINT,SIG_IGN)和signal(SIGQUIT,SIG_IGN),观察执行结果,并分析原因。
(4)进程的管道通信
编制一段程序,实现进程的管道通信,
使用系统调用pipe()建立一个管道文件;两个子进程P1和P2分别向管道各写一句话: Child1 is sending a message! Child2 is sending a message!
而父进程则从管道中读出来自于两个子进程的信息,显示在屏幕上。
要求父进程先接收子进程P1发来的消息,然后再接收子进程P2发来的消息。 设计题目2:银行家算法实现资源分配
要求如下:
(1)进程可动态地申请资源和释放资源,系统按各进程的申请动态地分配资源。 (2)要求程序具有显示和打印各进程的某一时刻的资源分配表和安全序列的功能。 (3)显示和打印各进程依次要求申请的资源号以及为某进程分配资源后的有关资源数据。
(4)可能用到的数据结构:
可利用资源向量Available。它是一个含有m个元素的数组,其中每个元素代表一类可利用资源的数目。
最大需求矩阵Max。n*m矩阵,表示n个进程的每一个对m类资源的最大需求。 分配矩阵Allocation 。n*m矩阵,表示每个进程已分配的每类资源的数目。 需求矩阵Need 。n*m矩阵,表示每个进程还需要各类资源数。 设计题目3:虚拟页面置换算法的实现
要求如下:
(1)至少实现OPT、FIFO、LRU三种置换算法中的两种。
(2)做成GUI界面最好,若不能,则要求界面尽量友好,便于操作。 (3)算法中涉及到的页面访问序列可以固定,也可以随机生成。
(4)在实现算法的同时要计算每种算法的缺页数。 (5)以表格的形式输出最终的页面置换结果。
注:以上三个题目任选其一,还可以自拟其它题目。
选择题目1的同学,应事先了解 (1) Linux的命令及使用格式;
可通过下面的几个任务熟悉有关文件(夹)操作的命令。
(2)在虚拟机vmware下让Linux加载U盘的方法。
(3)利用gcc、gdb编译、调试C/C++程序
第三篇:操作系统课程设计报告
操 作 系 统
课
程
设
计
实
验
报
告
学院:计算机科学与技术学院
班级:计112
学号:1113022032
姓名:
一、 实验名称:
用C++实现驱动调度算法、页面替换算法、银行家算法、处理器调度算法
二、 实验要求:
书写实验报告,包括的内容有:
(1) 实验题目
(2) 程序中使用的数据结构及主要文字说明
(3) 带有注释的源程序
(4) 执行程序说明,表明各进程控制快的初始状态,以及各算法的运行状态
(5) 通过实验后的收获与体会及对实验的改进意见和见解
二、实验目的:
通过自己编程来实现各类操作系统算法,进一步理解操作系统的概念及含义,提高对操作系统的认识,同时提高自己的动手实践能力。加强我们对各类算法的理解。
三、实验内容:
1、 实现页面替换算法
(1)FIFO 先进先出页面替换算法
(2)LRU最近最少使用页面替换算法
(3)LFU最少使用频率页面替换算法
2、银行家算法
3、实现驱动调度算法
(1)先来先服务算法
(2)电梯算法
(3)扫描算法
4、实现处理器调度
(1) 先进先出处理器调度
(2) 时间片轮转法
(3) 优先级调度
四、实验原理:
1、页面替换算法
先进先出页面置换算法:该算法总是淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面加以淘汰。将已调入内存的页面按先后次序链接成一个队列,将最先调入的页面与新页面进行置换
最近最久未使用置换算法:该算法是利用“最近的过去”作为“最近的将来”,将最近最久未使用的页面加以淘汰。将已调入内存的页面按先后顺序链接成一个队列,为每一个页面增加一个访问字段,用来记录一个页面自上次被访问以来所经历的是时间t,当需淘汰一个页面时,选择现有页面中其t值最大,即最近最久未使用的页面加以淘汰
2、银行家算法
先对用户提出的请求进行合法性检查,即检查请求的是不大于需要的,是否不大于可利用的。若请求合法,则进行试分配。最后对试分配后的状态调用安全性检查算法进行安全性检查。若安全,则分配,否则,不分配,恢复原来状态,拒绝申请。
3、驱动调度算法
先进先出算法(FIFO):总是严格按时间顺序对磁盘请求予以处理。算法实现简单、易于理解并且相对公平,不会发生进程饿死现象。但该算法可能会移动的柱面数较多并且会
经常更换移动方向,效率有待提高
电梯调度算法:总是将一个方向上的请求全部处理完后,才改变方向继续处理其他请求。
扫描算法(scan algorithm):总是从最外向最内(或最内向最外)进行扫描,然后在从最内向最外(或最外向最内)扫描。该算法与电梯调度算法的区别是电梯调度在没有最外或最内的请求时不会移动到最外或最内柱面。
4、处理器调度算法
先进先出处理器调度:按照作业进入系统后备工作队列的先后次序来挑选作业,
先进入系统的作业将优先被挑选进入主存,创建用户进程,分配所需资源,然后移入就绪队列。
时间片轮转法调度算法:调度次序每次把CPU分配给就绪队列进程/线程使用规
定的时间间隔,就绪队列中每个进程/线程轮流的运行一个时间片,当时间片耗尽时,就强迫当前运行进程/线程让出处理器,转而排列到就绪队列尾部,等候下一轮调度。
优先级调度:根据确定的优先级来选取进程/线程,总是选择就绪队列中的优先
级最高者投入运行,即优先级越高,先被调用。
五、数据结构设计
对操作系统的各类算法设计数据结构如下:
页面替换算法:void FIFO();void LRU();void LFU();
银行家算法:void Init() 初始化算法
void Bank() 银行家算法
bool Safe() 安全性算法
驱动调度算法:
struct MagneticHead//磁头构成
{
int site;
int count;
bool direct;
};
struct Range//磁盘磁道范围
{
int mStart;
int mEnd;
};
struct RequestList//请求序列
{
int site;
bool state;
};
struct Data//基本数据集合
{
MagneticHead magneticHead;
RequestList *requestList;
int *executeList;
Range range;
int length;
};
处理器调度:
typedef struct pcb//时间片轮转法
{
char pname[N];
int runtime;
int arrivetime;
char state;
struct pcb*next;
}PCB;
typedef struct PCB1//先进先出服务
{
char ID[3];//进程号
char name[10];//进程名
char state;//运行状态
floatarrivetime;//到达时间
floatstarttime;//进程开始时间
floatfinishtime;//进程结束时间
floatservicetime;//服务时间
float turnaroundtime;//周转时间
float weightedturnaroundtime;//带权周转时间
struct PCB1 *next;//指向下个进程
}pcb1;
struct pcb2 {优先级调度
char name[10];
char state;
int super;
int ntime;
int rtime;
struct pcb2* link;
}*ready=NULL,*d;
typedef struct pcb2 PCB2;
六、课程设计总结
在本次课程设计中,就是讲平时所做的实验结合起来,实现操作系统的各类算法,了解操作系统的运行原理以及其基本概念,更好的将操作系统的原理很好的展现出来。同时,在本次实验中遇到了很多问题,需要我们仔细的检查和修改。其次,实验中为了能更好的体现各类算法的运行情况,需要做一个清晰的界面,以能清楚地看出运行结果。
第四篇:操作系统课程设计文件管理
#include "stdio.h" #include "string.h" #include "malloc.h"
#include "stdlib.h"
#define MAX 1000 struct file/*普通文件的结构体*/ { //int type;//0无作用,当做一个空节点存在;1为记录型文件;2为执行文件
//前两个变量为文件的权限设置,1为允许操作,0为不允许操作
int write;//可写
int read;//可读
int length;//文件的长度
char ch[MAX]; }; typedef struct file File;
typedef struct ffile/*定义文件类型的结构体*/ { int type;//1为文件夹; 2为文件;
char name[20];//文件(夹)名字
int open;//文件打开标志,0为关,1为开
File iffile;//如果为文件时有的信息
struct ffile *parent;//指向上一级文件的指针
struct ffile *brother;//指向同级兄弟文件(夹)的指针
struct ffile *child;//指向下一级文件(夹)的指针 }Ffile; typedef Ffile *FFile;
/*typedef struct Open/*记录打开文件的结构体 { char name[20];//记录打开文件(夹)的名字
FFile* add;//记录打开文件上一级文件地址的指针 }Open;*/
//全局变量
FFile user1;//用户1 FFile user2;//用户2 FFile copyf;//记录被复制文件(夹)的上一级文件地址 //Open openf[20];//记录打开文件的队列
FFile init(void)/*初始化,创建根结点*/ { FFile c; c=(Ffile*)malloc(sizeof(Ffile));
c->type=2; c->open=0; //c->iffile.type=2; c->iffile.write=1; c->iffile.read=1; c->iffile.length=0; strcpy(c->name,"file1"); c->parent=NULL; c->child=NULL; c->brother=NULL; strcpy(c->iffile.ch,"NULL"); return(c); }
/*void initopen() { int a,b; a=20; for(b=1;b<=a;b++) {
openf[b].add=NULL; } }*/
//传递要显示文件的parent的地址
void show(FFile user)/*显示当前界面存在的文件*/ { user=user->child; if(user==NULL) {
printf("该文件内没有任何文件(夹)。 "); return; } printf(" "); for(;user!=NULL;){ printf("<%s",user->name); if(user->type==2) {
/*if(user->iffile.type==1)
printf("/记录型文件/");
else
printf("/执行文件/");*/
printf("/%dk",user->iffile.length); } else {
printf("/文件夹");
}
printf("> ");
user=user->brother; } }
void creatf(FFile user)/*创建文件 || 文件夹*/ { FFile parent; char ch[20]; //FFile user0; //parent=(Ffile*)malloc(sizeof(Ffile)); parent=user; printf("输入要创建文件(夹)的名字: ");
scanf("%s",ch); if(user->child==NULL) {
user->child=(Ffile*)malloc(sizeof(Ffile));
user=user->child; }else {
user=user->child;
for(;;)
{
if(user->type==0)//开端的空结点,用新结点覆盖
break;
if(!strcmp(user->name,ch))
{
printf("错误:该文件名已经存在,文件(夹)创建失败! ");
return;
}
if(user->brother==NULL)
{
user->brother=(Ffile*)malloc(sizeof(Ffile));
user=user->brother;
break;
}
user=user->brother;
}
} }
//设置新文件(夹)的信息 strcpy(user->name,ch); printf("选择创建对象:1文件夹; 2文件; "); scanf("%d",&user->type); user->open=0; if(user->type==2)//添加文件信息 {
//printf("选择文件类型:1记录型文件;2执行文件; "); //scanf("%d",&user->iffile.type); printf("能否对文件进行读:0禁止;1允许; "); scanf("%d",&user->iffile.read); printf("能否对文件进行写:0禁止;1允许; "); scanf("%d",&user->iffile.write); //printf("设置文件大小(单位:K): "); //scanf("%d",&user->iffile.length); user->iffile.length=0; strcpy(user->iffile.ch,"NULL"); } user->brother=NULL; user->child=NULL; user->parent=parent; printf("文件创建成功! "); void deletechildtree(FFile user)/*删除子树--结合deletefile();使用*/ { if (user->brother!=NULL)//从下到上,从右到左删除
{
deletechildtree(user->brother); } if (user->child!=NULL) {
deletechildtree(user->child); } if(user!=NULL) {
free(user); } }
void deletefile(FFile user,char ch[20])/*删除文件 || 文件夹*/ { FFile p,parent;
int a; parent=user; if(user->child==NULL) { printf("错误:删除失败,该目录下没有可删除的文件(夹)! "); return; } user=user->child; p=user; for(a=1;;a++)//找出要删除文件的所在位置 { if(!strcmp(user->name,ch))
break; if(user->brother==NULL) {
printf("错误:删除失败,当前位置没有该文件! ");
return; }
if(a>1)
p=user; user=user->brother; } if(user->open==1)//判断文件的开关情况 {
} printf("错误:删除失败,选择文件处于打开状态! "); return; if(p==user)//被删文件在文件队列的开头 { if(user->brother==NULL)//该文件队列只有有一个文件
{
parent->child=NULL;
if(user->child!=NULL)//删除的是文件(夹)子树
{
deletechildtree(user); }else {
free(user);//删除的是文件(夹)结点
} printf("删除成功! "); return; } //文件队列有多个文件 p=user->brother;
} parent->child=p; p->parent=parent; if(user->child!=NULL) { deletechildtree(user); }else { free(user); } printf("删除成功! "); return; else//被删文件不在队列开头 {
if(user->brother==NULL)//被删文件在文件队列最末尾 { p->brother=NULL; if(user->child!=NULL) {
deletechildtree(user); }else {
free(user); }
} printf("删除成功! "); return;
//被删文件在文件队列中间
p->brother=user->brother;
if(user->child!=NULL)
{
deletechildtree(user);
}
else
{
free(user);
} } printf("删除成功! "); }
FFile openfolder(FFile user)/*打开文件夹*/ {
} //int a,b; //a=0; /*if(user->child==NULL) { user->child=(Ffile*)malloc(sizeof(Ffile)); user->child->type=0; user->child->brother=NULL; user->child->parent=user; user->child->child=NULL;
} /*for(b=1;b<=20;b++) { if(openf[b].add!=NULL)
a++; } if(a==20) { printf("错误:打开列表溢出!"); return(user); } for(b=1;;b++) { if(openf[b].add==NULL)
break; }*/
user->open=1;//设置文件为打开 //strcpy(openf[b].name,user->name); //openf[b].add=user; printf("文件夹打开成功。 "); return(user);//返回被打开的文件夹的地址
void openfile(FFile user)/*打开普通文件*/ { if(user->open==1) {
printf("错误:打开失败,此文件已经被打开! ");
return; } user->open=1; printf("普通文件打开成功! "); }
FFile openff(FFile user)/*打开文件(夹)*/ {
char ch[20]; FFile parent;
int a; printf("选择要打开的文件名: "); scanf("%s",ch);
parent=user; if(user->child==NULL) {
printf("错误:打开失败,该目录下没有可打开的文件(夹)! "); return(parent); } user=user->child; for(a=1;;a++)//找出要打开文件的所在位置 { if(!strcmp(user->name,ch))
break; if(user->brother==NULL) {
printf("错误:打开失败,当前位置没有该文件! ");
return(parent); }
user=user->brother; } if(user->type==1) {
printf("开始打开文件夹。。。 "); user=openfolder(user); } else if(user->type==2) {
printf("开始打开普通文件。。。 ");
openfile(user);
user=user->parent; } return(user); }
void closefile(FFile user)/*关闭普通文件*/ {
char ch[20]; int a; printf("选择要打开的文件名: "); scanf("%s",ch); if(user->child==NULL) { printf("错误:关闭失败,该目录下没有可关闭的文件! "); return; } user=user->child; for(a=1;;a++)//找出要关闭文件的所在位置 { if(!strcmp(user->name,ch))
break; if(user->brother==NULL) {
printf("错误:关闭失败,当前位置没有该文件! ");
return; }
user=user->brother; } if(user->open==0) {
printf("错误:关闭失败,该文件已经是关闭状态! ");
return; } user->open=0; printf("文件已经成功关闭!"); } /*没有文件夹关闭原因:
文件夹一打开就会跳向打开的新文件里 而文件夹关闭就会直接返回上一级的目录, 若想整个文件夹都关闭,直接退出就可以了 因此不会直接关闭某个特定的文件*/
FFile backf(FFile user)/*返回上一层目录*/ { if(user->parent==NULL) {
printf("错误:返回失败,此处是最顶层目录! ");
return(user); }
} user->open=0; user=user->parent; return(user); void readfile(FFile user)/*读文件*/ { char ch[20]; int a;
printf("选择要读取的文件名: "); scanf("%s",ch); if(user->child==NULL) { printf("错误:读取失败,该目录下没有可读取的文件! "); return; } user=user->child; for(a=1;;a++)//找出要读取文件的所在位置 { if(!strcmp(user->name,ch))
break; if(user->brother==NULL) {
printf("错误:读取失败,当前位置没有该文件! ");
return; }
user=user->brother; } if(user->open==0) { printf("错误:文件读取失败,该文件处于关闭状态! "); return; } else if(user->iffile.read==0) { printf("错误:文件读取失败,该文件受保护,禁止读取! "); return; } printf("读操作,该文件中的内容: "); if(!strcmp(user->iffile.ch,"NULL")) { printf("该文件内没有可读内容! "); return;
} } printf("%s ",user->iffile.ch); printf("文件读取成功! "); void writefile(FFile user)/*写文件*/ { char ch[20]; int a;
} printf("选择要进行写操作的文件名: "); scanf("%s",ch); if(user->child==NULL) { printf("错误:写操作失败,该目录下没有可写的文件! "); return; } user=user->child; for(a=1;;a++)//找出要读取文件的所在位置 { if(!strcmp(user->name,ch))
break; if(user->brother==NULL) {
printf("错误:写操作失败,当前位置没有该文件! ");
return; }
user=user->brother; } if(user->open==0) { printf("错误:文件写操作失败,该文件处于关闭状态! "); return; } else if(user->iffile.write==0) { printf("错误:文件写操作失败,该文件受保护,禁止写! "); return; } printf("写操作,输入内容: "); scanf("%s",user->iffile.ch); user->iffile.length=strlen(user->iffile.ch); printf("文件进行写操作成功! ");
FFile copyfile(FFile user,FFile copyf)/*拷贝文件*/ { char ch[20]; int a; printf("选择要进行拷贝的文件(夹)名: "); scanf("%s",ch);
if(user->child==NULL) {
printf("错误:拷贝失败,该目录下没有可拷贝的文件! ");
return(NULL); } user=user->child; for(a=1;;a++)//找出要拷贝文件的所在位置,用user替代
{
if(!strcmp(user->name,ch))
break;
if(user->brother==NULL)
{
printf("错误:拷贝失败,当前位置没有该文件! ");
return(NULL);
}
user=user->brother; } copyf=user;
} printf("拷贝成功! "); return(copyf); FFile fenpei(FFile copyf,FFile user,FFile parent)/*粘贴时,给已拷贝项分配内存空间,以及给对应信息赋值*/ { user=(Ffile*)malloc(sizeof(Ffile));
//parent对child的连接,以及brother之间的连接已经完成
if(copyf->brother==NULL && copyf->child==NULL) {
user->parent=parent;
user->child=NULL;
user->brother=NULL; }
else{ if(copyf->brother!=NULL) {
user->brother=fenpei(copyf->brother,user->brother,parent); //brother连接,兄弟节点有同一个父结点
user->brother->parent=user->parent; } else { user->brother=NULL; } if(copyf->child!=NULL) { //parent=p; user->child=fenpei(copyf->child,user->child,user);
user->child->parent=user;//完成child对parent的连接
//child连接,自己孩子的父结点就是自己
} else {
user->child=NULL;
user->child->parent=user; } }
//设置结点对应的信息
strcpy(user->name,copyf->name); user->open=copyf->open; user->type=copyf->type; if(user->type==2) {
user->iffile.length=copyf->iffile.length;
user->iffile.read=copyf->iffile.read;
//user->iffile.type=copyf->iffile.type;
user->iffile.write=copyf->iffile.write;
strcpy(user->iffile.ch,copyf->iffile.ch); }
return(user); }
void prastefile(FFile user,FFile copyf)/*粘贴文件*/ //user是要粘贴的地方,copyf是要粘贴的内容, //有相同文件名的会判断会不会覆盖,或者是重命名 //在原树中进行新建操作 { int i,j; char ch[20]; FFile p,user0,parent; parent=user;//记录父结点
user=user->child;
p=user;//记录当前结点的前一个brother结点 strcpy(ch,"NULL"); if(copyf==NULL)//判断有没有拷贝文件 {
printf("错误:粘贴失败,还没有拷贝任何文件(夹)! ");
return; }
//p=(Ffile*)malloc(sizeof(Ffile)); //p->child=(Ffile*)malloc(sizeof(Ffile)); //先给粘贴项分配内存空间
//p->child=fenpei(copyf,p->child,p);
if(user==NULL) //当前位置没有任何文件结点
{
} user=fenpei(copyf,user,parent);//是他自己要分配,不是孩子结点!!! parent->child=user; user->brother=NULL; user->parent=parent; return; //该位置没有任何文件 for(j=1;;j++) { if(user->type==0) //开端的空结点,用新结点覆盖,即:当前位置没有文件结点
{
user=user->parent;
deletechildtree(p);
user=fenpei(copyf,user->child,user);//返还增加的结点
user->brother=NULL;
user->parent=parent;
parent->child=user;
} return; if(!strcmp(user->name,copyf->name)) {
printf("提示:该文件名已经存在! ");
printf("请重命名文件: ");
printf("输入新文件名: ");
scanf("%s",ch);
} if(user->brother==NULL) //普通的退出条件
{
break; } p=user; user=user->brother; } user->brother=fenpei(copyf,user->brother,user->parent); user->brother->parent=user->parent; //若要更名,粘贴分配完内存空间返回时再改变
if(strcmp(ch,"NULL"))
strcpy(user->brother->name,ch); printf("粘贴成功。 "); }
void showroute(FFile user)/*显示当前路径*/ { if(user->parent!=NULL) {
showroute(user->parent); } printf("%s/",user->name);//路径中每个结点的输出项 }
void change(FFile user) { char ch[20]; int a,b;
if(user->child==NULL)
{
} printf("错误:属性修改失败,该目录下没有可修改的文件! "); return; printf("选择要进行属性修改的文件(夹)名: "); scanf("%s",ch); user=user->child; for(a=1;;a++)//找出要拷贝文件的所在位置,用user替代 { if(!strcmp(user->name,ch))
break; if(user->brother==NULL) {
printf("错误:属性修改失败,当前位置没有该文件! ");
return; }
user=user->brother; } if(user->type==1) { printf("错误:文件夹不能进行属性修改! "); return; } for(;;) {
printf("1.修改读权限; "); printf("2.修改写权限; "); printf("3.返回; "); printf("选择操作: "); scanf("%d",&a); if(a==1) { printf("0.禁止;
1.允许; "); printf("请选择: "); scanf("%d",&b); user->iffile.read=b; printf("修改成功! "); } else if(a==2) { printf("0.禁止;
1.允许; "); printf("请选择: "); scanf("%d",&b); user->iffile.write=b;
}
} printf("修改成功! "); } else if(a==3) { return; } else { } printf("错误:没有该操作! "); void main()/*主函数*/ {
FFile d,e,f;//f记录当前显示界面父结点位置 int a,b,c; char ch[20]; a=0; printf("******************************目录****************************** "); printf("
1.选择用户 "); printf("
2.退出 ");
printf("**************************************************************** "); for(;;) {
printf("选择操作: "); scanf("%d",&a); if (a==1) { printf("选择用户: "); printf("1.user1; 2.user2; "); scanf("%d",&b); break; } else if (a==2) { printf("欢迎使用。 "); exit(0);//系统退出的操作码 } else { printf("错误:没有该操作! ");
} } //初始化打开列表 //initopen(); //初始化各个用户的信息
//copyf=(Ffile*)malloc(sizeof(Ffile)); //copyf=NULL; copyf=NULL; user1=init(); strcpy(user1->name,"user1"); user2=init(); strcpy(user2->name,"user2"); d=init(); e=init(); user1->child=d; user2->child=e; d->parent=user1; e->parent=user2; printf("%d",user1->child->type); if(b==1){ printf("已经进入user1系统 "); f=user1; show(user1); }else{
} printf("已经进入user2系统 "); f=user2; show(user2);
for(;;){ printf("**************************************************************** "); printf("1.创建文件(夹)
5.读文件
9.显示当前路径
"); printf("2.删除文件(夹)
6.写文件
10.返回上一层目录
"); printf("3.打开文件(夹)
7.拷贝文件
11.改变普通文件属性 "); printf("4.关闭普通文件
8.粘贴文件
12.退出 "); printf("**************************************************************** "); printf("选择操作: "); scanf("%d",&c); if(c==12) {
break; }else if(c==1) { creatf(f); } else if(c==2) {
printf("选择要删除的文件(夹)的名字: "); scanf("%s",ch); deletefile(f,ch); } else if(c==3) { f=openff(f); } else if(c==4) { closefile(f); } else if(c==5) { readfile(f); } else if(c==6) { writefile(f); } else if(c==7) { copyf=copyfile(f,copyf); } else if(c==8) { prastefile(f,copyf); copyf=NULL; } else if(c==9) { printf("路径为: "); showroute(f); printf(" "); } else if(c==10) {
}
f=backf(f);
} else if(c==11) { change(f); } else { continue; } show(f); } printf("欢迎使用! ");
第五篇:《操作系统课程设计》内容要求
《操作系统课程设计》
注意事项:要求每个同学独立完成以下三个项目中的任两个,编程语言不限.
项目一:命令行解释程序
【教学内容】 利用C语言编写一个微型命令解释程序,体会操作系统作为用户与计算机接口的作用。巩固C语言编程能力。
1.所设计的微型命令解释程序具有下列5条命令 cdir (列出当前文件和目录)
ccopy 文件1 文件2
(拷贝文件) cerase 文件名 (删除文件) Cdis 字符串
(显示该字符串)
Cend (退出微型命令解释程序) 2.项目报告要求
列出采用的数据结构并加以说明。
打印一份源程序清单,并附加流程图与注释。
分析Windows操作系统和Linux操作系统的命令解释程序的不同之处。
【教学重点及难点】
重点:命令解释程序的作用。 难点:命令解释程序的实现原理。
【基本要求】
了解常用操作系统的命令操作方式和不同操作系统的命令解释程序。 理解命令解释程序的作用。 掌握命令解释程序的实现原理。
【主要实践教学条件】
IBM 586以上微型计算机及其兼容机。
Windows xp/2000 以上版本,Linux redhat9 以上版本。 TURBO C 2.0、VC++、其他高级语言或GCC编译器。
项目二:进程控制
【教学内容】 利用Linux进程控制部分的主要系统调用进行编程,实现对进程的创建、终止、同步和通信等控制,提高学生对进程控制系统调用的编程能力,加深对进程控制的理解。
1.实现对进程的如下控制操作 进程的创建和终止; 进程的状态转换; 进程之间的通信; 进程之间的互斥访问文件。 2.项目报告要求
列出采用的数据结构并加以说明。
打印一份源程序清单,并附加流程图与注释。
分析Windows操作系统和Linux操作系统的进程控制系统调用的不同之处。
【教学重点及难点】
重点:进程之间的通信。 难点:进程之间的互斥。
【基本要求】
了解常用操作系统的提供的常用进程控制类系统调用。 理解进程通信方式。 掌握用信号量实现进程互斥。
【主要实践教学条件】
IBM 586以上微型计算机及其兼容机。
Windows xp/2000 以上版本,Linux redhat9 以上版本。 TURBO C 2.0、VC++、其他高级语言或GCC编译器。
项目三:文件系统
【教学内容】模拟文件管理。设计并调试一个简单的文件系统,模拟文件操作命令的执行。深入了解主要文件操作命令的执行过程,掌握它们的基本实施方法。
1.实现文件系统的基本功能
设计一个支持n个用户的文件系统,每个用户可拥有多个文件。 采用二级或二级以上的多级文件目录管理。
对文件设置存取控制保护方式,如“只能执行”、“允许读”、“允许写”等。 系统的外部特征应接近于真实系统,可以设置下述文件操作命令:建立文件、打开文件、关闭文件、删除文件、读文件、写文件、复制文件、查询目录。 通过键盘使用该文件系统,系统应当显示操作命令的执行结果。 2.项目报告要求
列出采用的数据结构及并加以说明。
打印一份源程序清单,并附加流程图与注释。
分析Windows操作系统和Linux操作系统的文件系统的不同之处。 分析Windows操作系统和Linux操作系统的文件操作命令有何不同。 【教学重点及难点】
重点:文件系统的主要功能。
难点:文件系统的常用命令的主要工作。
【基本要求】
了解各种文件操作系统的异同。 理解常用操作系统支持的文件操作系统。 掌握文件系统的主要功能。
掌握文件系统的常用命令的主要工作。
【主要实践教学条件】
IBM 586以上微型计算机及其兼容机。
Windows xp/2000 以上版本,Linux redhat9 以上版本。 TURBO C 2.0、VC++、其他高级语言或GCC编译器。
、必备教材、实践教学指导书和参考资料
(一)必备教材
1.《操作系统实验教程(Linux版)》,潘景昌 编著,清华大学出版社,2010年第1版。
(二)实践教学指导书
1.《计算机操作系统实验与实践——基于Windows与Linux》,秦明 编著,清华大学出版社,2010年第1版。
2.《操作系统实验教程及Linux和Windows系统调用编程》,张丽芬 编著,清华大学出版社,2010年第1版。
(三)参考资料
1.《操作系统原理实用教程》,李俭 编著,清华大学出版社,2011年第1版。
2.《操作系统原理实验教程(基于Linux)》,胡峰松 编著,清华大学出版社,2010年第1版。
3.《计算机操作系统》,汤小丹 编著,西安电子科技大学出版社,2007年第3版。
、课外学习要求
1.项目一命令解释程序课外学习要求
了解Windows操作系统和Linux操作系统的命令解释程序,并分析二者的不同之处。
会使用Windows操作系统和Linux操作系统的常用命令。 完成项目一的报告。 2.项目二进程控制课外学习要求
了解Windows操作系统和Linux操作系统的进程控制类常用系统调用,并分析二者的不同之处。
了解Windows操作系统和Linux操作系统中实现进程同步的系统调用方法有哪些,并能利用该方法够编程实现进程的同步。 完成项目二的报告。 3.项目三文件系统课外学习要求
了解Windows操作系统和Linux操作系统的文件系统,并分析二者的不同之处。 会使用Windows操作系统和Linux操作系统的文件操作命令,分析两种操作系统支持的文件操作命令有何不同。 完成项目三的报告。
考核及成绩评定方式
1. 考核方式
本课程设计中的三个项目都属于综合设计类项目,所以对每个项目进行验收时,通过学生演示程序实现的功能,检查学生完成的程序是否符合项目要求,结合源程序代码对学生进行质疑,每个项目有一个验收成绩。 2. 成绩评定方式
总评成绩=课程设计报告(30%)+平时 (70%)。平时成绩包括考勤、提问、质疑和课程设计期间表现等,主要考查学生日常项目完成情况,注重对学生能力的考核。课程设计报告要符合要求并独立完成。
【操作系统课程设计完整】相关文章:
操作系统课程设计06-25
实时操作系统课程设计02-27
通信系统课程设计07-17
问卷系统课程设计07-18
信息系统课程设计07-22
企业信息系统课程设计02-06
管理信息系统课程设计11-26
通信系统课程设计要求03-09
通信系统综合课程设计03-09
物流系统规划课程设计03-14