第一篇:操作系统课程设计题目
辽宁科技大学操作系统课程设计指导书
一、课程设计目的和要求
本设计是专业基础课《操作系统》的课程设计。由于操作系统课的学时有限,安排实验的次数不多。为了进一步巩固实验成果,加强理论联系实际、分析问题、解决问题的能力,加深对操作系统的基本概念、原理、技术和方法的理解,特安排此次课程设计。它是操作系统课程的实践环节。由于具体的操作系统相当复杂,在短短的一周之内,不可能对所有管理系统进行详细地分析。因此,选择了操作系统中最重要的管理之一进程管理(或进程的死锁、页面置换算法)作为本设计的任务。另外,通过此次设计使学生在使用系统调用的同时,进一步了解系统内部是如何实现系统调用的全过程,使学生在更深层次上对操作系统有所了解。要求:
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++程序
第二篇:《操作系统课程设计》题目要求
操作系统课程设计要求
一.设计目的
熟悉Linux编程环境,加强对Linux命令的理解及函数的运用
二.设计内容
1.在Linux环境下模拟实现简单命令解释器。(1)要求实现的基本命令包括:
pwd
//显示当前所在目录的路径名
dir <目录名>
//列出指定目录名中的所有目录及文件 cd <目录名或路径>
//改变当前工作目录 newdir <目录名>
//新建目录 deldir <目录名>
//删除目录
exit //退出命令解释程序(2)可选做的扩展命令包括:
rename <旧文件名> <新文件名> //重命名一个文件或目录
find <目录>-name <待查找的文件名> //在指定的目录及其子目录中查找指定的文件
date //显示当前日期(3)提示:整个程序的大致框架可参考如下:
while(exit未被输入){
接收键盘的一行输入
分析输入的命令
对输入的命令进行处理,调用系统函数实现功能
} 2.设计要求
(1)设计必须在Linux环境下进行。
(2)命令解释程序的提示符为:姓名拼音@(3)程序编写中不得使用system()系统调用。
(4)整个程序必须严格经过测试,完成所有基本功能。源程序应有较详尽的注释。
3.可能用到的系统调用:
open(),close(),read(),write(),creat()chdir(), opendir(),readdir(),rewinddir(),closedir(),rmdir(),mkdir()getcwd(), ftw()
time(), localtime(), asctime()三. 提交要求:
1.完成的源程序和可执行程序必须保存在Linux服务器上。
2.要求实现的基本命令必须全部实现。完成可选做的扩展命令将得到较高的分数。容错性强和功能细节考虑更完全也将得到较高的分数。
3.每位同学必须完成操作系统课程设计说明书并上交纸质打印版(不少于3000字),设计说明书格式请从ftp下载《操作系统课程设计说明书(模板)》查看。(学习委员收齐后交到老师办公室)。说明书电子版提交到老师的FTP
11计算机2班的同学: 交给韦婷老师
说明书电子版提交到:ftp://we:345678@10.5.1.请提交到该ftp的“/作业/操作系统课程设计/”文件夹中 每位同学的课程设计说明书按以下格式命名: “班内序号-姓名.doc”
例如:05-李凯.doc
4.独立完成,不得抄袭,凡是发现抄袭的(无论抄与被抄者),均不及格。5.课程设计上交截止日期: 11月12 日
6.设计提交后将抽取一部分同学进行答辩,答辩时间另行通知。
注意:
1.Linux服务器远程连接方式:telnet 10.5.1.6(telnet连接服务器的过程可能需要十几秒,属正常现象,请耐心等待)2.登陆的用户名和密码 11计算机2班的同学:
用户名:112班内序号
例如: 11计算机2班的5号同学的用户名是:11205
初始密码:123456
3.在Linux环境编程,若要使用cin、cout,则必须用
#include
4.本课程设计所需资料从ftp://we:345678@10.5.1.5 “/下载/操作系统课程设计/” 文件夹中下载。
第三篇:操作系统课程设计题目及代码
题目一
模拟操作系统设计
设计一个模拟操作系统管理程序,实现下列管理功能: 1.内存管理功能 2.文件管理功能 3.磁盘管理功能
题目二
虚拟存储器各页面置换算法的实现与比较 内 容:设计一个虚拟存储区和内存工作区,通过产生一个随机数的方法得到一个页面序列,假设内存给定的页面数由键盘输入,分别计算使用下述各方法时的内存命中率:
先进先出算法(FIFO)、最近最少使用算法(LRU)、最佳淘汰算法(OPT)、最少访问页面算法(LFU)等。
参考资料
题目二
资料
虚拟存储器各页面置换算法的实现与比较
1.实验目的
存储管理的主要功能之一是合理的分配空间。请求页式管理是一种常用的虚拟存储管理技术。
本实验的目的是通过请求页式存储管理中页面置换算法模拟设计,了解虚拟存储技术的特点,掌握请求页式存储管理的页面置换算法。2.实验内容
(1)通过随机数产生一个指令序列,共320条指令。指令的地址按下述原则生成: 1)50%的指令是顺序执行的;
2)25%的指令是均匀分布在前地址部分; 3)25%的指令是均匀分布在后地址部分; 具体的实施方法是:
1)在[0,319]的指令地址之间随机选取一起点m; 2)顺序执行一条指令,即执行地址为m+1的指令;
3)在前地址[0,m+1]中随机选取一条指令并执行,该指令的地址为m'; 4)顺序执行一条指令,其地址为m'+1;
5)在后地址[m'+2,319]中随机选取一条指令并执行; 6)重复上述步骤1)-5),直到执行320次指令。(2)将指令序列变换成为页地址流 设:1)页面大小为1k;
2)用户内存容量为4页到32页; 3)用户虚存容量为32k; 在用户虚存中,按每k存放10条指令排列虚存地址,即320条指令在虚存中的存放方式为: 第0条-第9条指令为第0页(对应虚存地址为[0,9]); 第10条-第19条指令为第1页(对应虚存地址为[10,19]);
...第310条-第319条指令为第31页(对应虚存地址为[310,319]);
按以上方式,用户指令可组成为32页。
(3)计算并输出下列各种算法在不同内存容量下的命中率。1)先进先出的算法(FIFO); 2)最近最少使用算法(LRR);3)最佳淘汰算法(OPT):先淘汰最不常用的页地址; 4)最少访问页面算法(LF.U); 5)最近最不经常使用算法(NUR)。其中3)和4)为选择内容。命中率=1-页面失效次数/页地址流长度
在本实验中,页地址流长度为320,页面失效次数为每次访问相应指令时,该指令所对应的页不在内存的次数。3.随机数产生办法
关于随机数产生办法,Linux或Unix系统提供函数srand()和rand(),分别进行初始化和产生随机数。例如: srand();
语句可初始化一个随机数; a[0]=10*rand()/32767*319+1;a[1]=10*rand()/32767*a[0];
..语句可用来产生a[0]与a[1]中的随机数。
提示:
首先用Srand()和rand()函数定义和产生指令序列,然后将指令序列变换成相应的页地址流,并针对不同的算法计算出相应的命中率。
命中率=1-页面失效次数/页地址流长度
1、数据结构
(1)页面类型 typedef struct{
int pn,pfn,counter,time;}pl-type;
其中pn为页号,pfn为页面号,count为一个周期内访问该页面的次数,time为访问时间。
(2)页面控制结构 pfc_struct{
int pn,pfn;
struct pfc_struct *next;
};typedef struct
pfc_struct pfc_type;pfc_type
pfc[total_vp],*freepf_head,*busypf_head;pfc_type *busypf_tail;其中,pfc[total_vp]定义用户进程虚页控制结构,*freepf_head为空页面头的指针,*busypf_head为忙页面头的指针,*busyf_tail为忙页面尾的指针。
2、函数定义
(1)Void initialize():初始化函数,给每个相关的页面赋值。(2)Void FIFO():计算使用FIFO算法时的命中率。(2)Void LRU():计算使用FIFO算法时的命中率。(4)VoidOPT():计算使用OPT算法时的命中率。(5)Void LFU():计算使用LFU算法时的命中率。(6)Void
NUR():计算使用NUR算法时的命中率。
3、变量定义
(1)int a[tatal_instruction] :指令流数据组。
(2)int page[total_instruction]:每条指令所属页号。
(3)int offset[total_instruction]:每页装入不敷出0条指令后取模运算页号偏移量。(4)int total_pf:用户进程的内存页面数。(5)int diseffect:页面失效次数。
程序清单
程序: 程序: #include “stdio.h” #include “process.h” #include “stdlib.h” #define TRUE 1 #define FALSE 0 #define INVALID-1 #define null 0 #define total_instruction 320 /*指令流长*/ #define total_vp 32 /*虚页长*/ #define clear_period 50 /*清0周期*/ typedef struct { int pn,pfn,counter,time;}pl_type;pl_type pl[total_vp];/*页面数据结构*/ struct pfc_struct{ /*页面控制结构*/ int pn,pfn;struct pfc_struct *next;};typedef struct pfc_struct pfc_type;pfc_type pfc[total_vp],*freepf_head,*busypf_head,*busypf_tail;int diseffect,a[total_instruction];int page[total_instruction],offset[total_instruction];void initialize();void FIFO();void LRU();void OPT();void LFU();void NUR();main(){ int S,i,j;srand(getpid()*10);/*由于每次运行时进程号不同,故可用来作为初始化随机数队
列的种子*/ S=(float)319*rand()/32767+1;for(i=0;i
busypf_head=busypf_tail=freepf_head;else {busypf_tail->next=freepf_head;busypf_tail=freepf_head;} freepf_head=p;} } printf(“FIFO:%6.4”,1-(float)diseffect/320);} void LRU(total_pf)/*LRU*/ int total_pf;{ int min,minj,i,j,present_time;initialize(total_pf);present_time=0;for(i=0;i 1、操作系统实验教程 张丽芬编著 清华大学出版社 2、操作系统原理实验教程(基于Linux)胡峰松编 清华大学出版社 湖北民族学院信息工程学院11级计算机专业操作系统课程设计 (操作系统课程设计) 连续动态分区内存 管理模拟实现 学生姓名: 韩 慧 学生学号: 031140312 班 级: 031140--3 0311401、02、03、04班制 二〇一三年十二月 湖北民族学院信息工程学院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 湖北民族学院信息工程学院11级计算机专业操作系统课程设计 参考文献.........................................................................28 引言 操作系统是最重要的系统软件,同时也是最活跃的学科之一。我们通过操作系统可以理解计算机系统的资源如何组织,操作系统如何有效地管理这些系统资源,用户如何通过操作系统与计算机系统打交道。 存储器是计算机系统的重要组成部分,近年来,存储器容量虽然一直在不断扩大,但仍不能满足现代软件发展的需要,因此,存储器仍然是一种宝贵而又紧俏的资源。如何对它加以有效的管理,不仅直接影响到存储器的利用率,而且还对系统性能有重大影响。而动态分区分配属于连续分配的一种方式,它至今仍在内存分配方式中占有一席之地。 课程设计目的和内容: 理解内存管理的相关理论,掌握连续动态分区内存管理的理论;通过对实际问题的编程实现,获得实际应用和编程能力。 编写程序实现连续动态分区内存管理方式,该程序管理一块虚拟内存,实现内存分配和回收功能。分析并实现四种内存分配算法,即最先适应算法,下次最先适应算法,最优适应算法,最坏适应算法。内存分配算法和回收算法的实现。 需求分析 动态分区分配是根据进程的实际需要,动态地为之分配内存空间。在实现动态分区分配时,将涉及到分区分配中所用的数据结构、分区分配算法和分区的分配和回收操作这样三个问题。常用的数据结构有动态分区表和动态分区链。在对数据结构有一定掌握程度的情况下设计合理的数据结构来描述存储空间,实现分区存储管理的内存分配功能,应该选择最合适的适应算法(首次适应算法,最佳适应算法,最后适应算法,最坏适应算法),在动态分区存储管理方式中主要实现内存分配和内存回收算法,在这些存储管理中间必然会有碎片的产生,当碎片产生时,进行碎片的拼接等相关的内容 概要设计 本程序采用机构化模块化的设计方法,共分为四大模块。⑴最先适应算法实现 从空闲分区表的第一个表目起查找该表,把最先能够满足要求的空闲区分配给作业,这种方法目的在于减少查找时间。为适应这种算法,空闲分区表(空闲区链)中的空闲分区要按地址由低到高进行排序。该算法优先使用低址部分空闲区,在低址空间造成许多小的空闲区,在高地址空间保留大的空闲区。⑵下次适应分配算法实现 湖北民族学院信息工程学院11级计算机专业操作系统课程设计 该算法是最先适应算法的变种。在分配内存空间时,不再每次从表头(链首)开始查找,而是从上次找到空闲区的下一个空闲开始查找,直到找到第一个能满足要求的的空闲区为止,并从中划出一块与请求大小相等的内存空间分配给作业。该算法能使内存中的空闲区分布得较均匀。⑶最优适应算法实现 它从全部空闲区中找出能满足作业要求的、且大小最小的空闲分区,这种方法能使碎片尽量小。为适应此算法,空闲分区表(空闲区链)中的空闲分区要按从小到大进行排序,自表头开始查找到第一个满足要求的自由分区分配。⑷最坏算法实现 最坏适应分配算法要扫描整个空闲分区或链表,总是挑选一个最大的空闲分区分割给作业使用。该算法要求将所有的空闲分区按其容量从大到小的顺序形成一空闲分区链,查找时只要看第一个分区能否满足作业要求。 开发环境: win7 下 VC++6.0 系统分析设计: 相关算法原理,算法流程图,涉及的数据结构内容都相应包含在各章节中 有关了解内存管理的相关理论 内存管理概念: 内存管理,是指软件运行时对计算机内存资源的分配和使用的技术。其最主要的目的是如何高效,快速的分配,并且在适当的时候释放和回收内存资源。内存不是预先划分好的,而是在系统运行的过程中建立分区.当作业装入主存时,根据作业所需要的主存容量查看是否有足够的主存空间,若有则按需要分割一个分区给该作业;否则令该作业等待.分区长度不固定分区个数不固定。这种存储管理的方法克服了固定分区严重浪费主存的问题,提高了主存资源的利用率。 内存管理的必要性: 内存管理对于编写出高效率的 Windows 程序是非常重要的,这是因为Windows 是多任务系统,它的内存管理和单任务的 DOS 相比有很大的差异。DOS是单任务操作系统,应用程序分配到内存后,如果它不主动释放,系统是不会对它作任何改变的;但 Windows 却不然,它在同一时刻可能有多个应用程序共享内存,有时为了使某个任务更好地执行,Windows 系统可能会对其它任务分配的内存进行移动,甚至删除。因此,我们在 Windows 应用程序中使用内存时,要遵循Windows 内存管理的一些约定,以尽量提高 Windows 内存的利用率。湖北民族学院信息工程学院11级计算机专业操作系统课程设计 1.3 内存的物理组织: 物理地址: 把内存分成若干个大小相等的存储单元,每个存储单元占 8 位,称作字节(byte)。每个单元给一个编号,这个编号称为物理地址(内存地址、绝对地址、实地址)。 二、物理地址空间: 物理地址的集合称为物理地址空间(主存地址空间),它是一个一维空间。 什么是虚拟内存: 虚拟内存是内存管理技术的一个极其实用的创新。它是一段程序(由操作系统调度),持续监控着所有物理内存中的代码段、数据段,并保证他们在运行中的效率以及可靠性,对于每个用户层(user-level)的进程分配一段虚拟内存空间。当进程建立时,不需要在物理内存件之间搬移数据,数据储存于磁盘内的虚拟内存空间,也不需要为该进程去配置主内存空间,只有当该进程被被调用的时候才会被加载到主内存。 连续动态分区内存管理方式的实现 在早期的操作系统中,主存分配广泛采用连续分配方式。连续分配方式,是指为一个用户程序分配一个连续的内存空间,该连续内存空间指的的是物理内存。下面介绍连续分配的四种方式。 单一连续分配(单个分区) 最简单的存储管理方式,用于多道程序设计技术之前。内存分为系统区和用户区,系统区由操作系统使用。用户区作为一个连续的分区分配给一个作业。分区存储管理是满足多道程序设计的最简单的一种存储管理方法,它允许多 4个用户程序同时存在系统内存中,即共享内存空间。按分区划分方式可分为固定分区和可变分区。 固定分区存储管理 把内存的用户区预先划分成多个分区,每个分区大小可以相同,也可以不同。(分区的划分由计算机的操作员或者由操作系统给出,并给出主存分配表)分区个数固定,分区的大小固定。一个分区中可装入一个作业,作业执行过程中不会改变存放区域。早期的 IBM 的 OS/MFT(具有固定任务数的多道程序系统)采用了这种固定分区的方法。 可变分区存储管理(动态分区) 内存不是预先划分好的,而是在系统运行的过程中建立分区.当作业装入主存时,根据作业所需要的主存容量查看是否有足够的主存空间,若有则按需要分割一个分区给该作业;否则令该作业等待。分区长度不固定分区个数不固定。这种存储管理的方法克服了固定分区严重浪费主存的问题,提高了主存资源的利用率。IBM操作系统OS/MVT采用可变分区存储管理。湖北民族学院信息工程学院11级计算机专业操作系统课程设计 可重定位分区存储管理 解决碎片问题的一种简单方法是采用可重定位分区分配.。其中心思想是,把不同程序,且在内存中地址不连续的想法让他们连续。 例:内存中现有 3 个空闲区,现有一作业到达,要求获得 30k 内存空间,没有分区满足容量要求,若想把作业装入,可将内存中所有作业进行移动,这样把原来分散的空闲区汇集成一个大的空闲区。将内存中的作业进行移动使它们连接在一起把原来分散的多个小分区拼接成一个大的空闲区.这个过程称为”紧凑”或”移动”。需解决的问题:每次”紧凑”后程序或数据装入的物理地址变化采用动态重定位。 问题描述和分析 系统应利用某种分配算法,从空闲分区链表中找到所需大小的分区,如果空闲分区大小大于请求分区大小,则从该分区中按改请求的大小划分出一块内存空间大小划分出一块内存空间分配出去,余下的部分仍留在空闲链表中。然后,将分配区的首址返回给调用者。 当进程运行完毕师范内存时,系统根据回收区的首址,从空闲区中找到相应的插入点,此时可能出现以下四种情况之一: ⑴该空闲区的上下两相邻分区都是空闲区:将三个空闲区合并为一个空闲区。新空闲区的起始地址为上空闲区的起始地址,大小为三个空闲区之和。空闲区合并后,取消可用表或自由链中下空闲区的表目项或链指针,修改上空闲区的对应项。 ⑵该空闲区的上相邻区是空闲区:将释放区与上空闲区合并为一个空闲区,其起始地址为上空闲区的起始地址,大小为上空闲区与释放区之和。合并后,修改上空闲区对应的可用表的表目项或自由链指针。 ⑶该空闲区的下相邻区是空闲区:将释放区与下空闲区合并,并将释放区的起始地址作为合并区的起始地址。合并区的长度为释放区与下空闲区之和。同理,合并后修改可用表或自由链中相应的表目项或链指针。 ⑷两相邻区都不是空闲区:释放区作为一个新空闲可用区插入可用表或自由链。 程序流程图 内存分配流程图,如图 湖北民族学院信息工程学院11级计算机专业操作系统课程设计 从头开始查表检索完否?NY返回分区大小>所需大小N继续检索下一个表项Y分区大小-所需大小<=不可再分割大小N从该分区中划出所需大小的新分区Y将该分区从链中移出将该分区分配给请求者修改有关数据结构返回 内存回收流程图,如图 湖北民族学院信息工程学院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;湖北民族学院信息工程学院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(“n.......................欢迎来到动态分区存储管理系统..................nn”);printf(“...........................请选择要执行的算法:...........................n”);printf(“.........................1.最先适应算法 ...............................n”);printf(“.........................2.下次适应算法............................n”);printf(“..........................3.最优适应算法 ...............................n”);printf(“.........................4.最坏适应算法................................n”);printf(“........................................................................n”);printf(“请输入您的选择:”);scanf(“%d”,&t);int i;while(i!=5){ printf(“........................................................................n”); printf(“.........................操作菜单如下:(请选择).......................n”); printf(“..........................1.输入进程分配空间...........................n”); printf(“.........................2.进程撤销回收空间...........................n”); printf(“.........................3.输出所有空闲分区 ..........................n”); printf(“..........................4.输出所有已分配分区..........................n”); printf(“..........................5.退 出..........................n”); printf(“........................................................................n”); scanf(“%d”,&i); switch(i) { case 1: switch(t) { case 1: t1=FF();湖北民族学院信息工程学院11级计算机专业操作系统课程设计 break; case 2: t1=NF(); break; case 3: t1=BF(); break; case 4: t1=WF(); break; default: printf(“选择算法错误n”); return 1; } if(t1) printf(“分配空间成功n”); else printf(“分配空间失败n”); break; case 2: t1=recover(); if(t1) printf(“回收成功n”); else printf(“回收失败n”); break; case 3: Isprint(); break; case 4: Bsprint(); break; } } return 0;} 第三章 :分析并实现四种内存分配算法 最先适应算法 空闲区按地址从小到大的次序排列。 分配:当进程申请大小为 SIZE 的内存时,系统顺序查找空闲区表(链),直到找到容量满足要求(≥SIZE)的空闲区为止。从该空闲区中划出大小为 SIZE的分区分配给进程,余下的部分仍作为一个空闲区,但要修改其首址和大小。湖北民族学院信息工程学院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级计算机专业操作系统课程设计 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->from 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); 湖北民族学院信息工程学院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->from b=b->next;else break; //如果找到则为进程分配空间 湖北民族学院信息工程学院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指向修改结点的下一个 //循环查找 湖北民族学院信息工程学院11级计算机专业操作系统课程设计 j->r.name[i]=D.name[i]; } j->r.size=D.size; while(b->next) { if(b->next->from 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;湖北民族学院信息工程学院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->from 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指向空闲链表下一个结点 湖北民族学院信息工程学院11级计算机专业操作系统课程设计 while(b->next)置 //寻找插入到已分配链表中的位 { if(b->next->from 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)释放区不与任何空闲区相邻:将释放区作为一个空闲区,将其大小和首址插入到空闲区表的适当位置。 湖北民族学院信息工程学院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(“没找到这”进程n”);return 0;} //所回收进程与空闲结点上下都邻调试与操作说明 初始界面 程序初始界面,有四个块选择,选择要执行的算法,调试以最坏算法为例,如图 湖北民族学院信息工程学院11级计算机专业操作系统课程设计 选择最坏适应算法,如图 模拟内存分配 给进程a分配内存20,如图 湖北民族学院信息工程学院11级计算机专业操作系统课程设计 已分配分区说明表界面 同理,给进程b分配内存30,给进程c分配内存40,给进程d分配50,给进程e分配60,如图 空闲分区说明表界面 湖北民族学院信息工程学院11级计算机专业操作系统课程设计 查看空闲分区,如图 回收内存界面 回收进程b和d所占内存,如图 已分配分区说明表和空闲分区说明表 如图 湖北民族学院信息工程学院11级计算机专业操作系统课程设计 重新申请内存界面 再为新进程i分配内存30,如图 湖北民族学院信息工程学院11级计算机专业操作系统课程设计 根据最坏适应算法结合图所示可知,该算法将会从空闲分区表中选择一块最大的内存空间分配给进程i,从图也可看出该模拟算法实现了最坏适应算法 湖北民族学院信息工程学院11级计算机专业操作系统课程设计 总结与体会 本次做的课题是动态分区分配算法实现,此次课程设计成功实现了内存分配和内存回收,内存分配中包含了四种算法,分别是首次适应算法,循环首次适应算法,最佳适应算法和最坏适应算法。经编码调试,表明该程序模块是有效可行的。 通过这门课程的学习让我充分了解了内存管理的机制实现,从而更深一步的的对计算机 有了很多了解,这对于以后我们的研究和学习计算机系统起到了很重要的作用。 对于本次论文制作,自己的编程能力有所提高,对操作系统内存分配,存储空间的回收都有全新的认识。 在这次操作系统课程设计中,我使用了c++编写系统软件,对os中可变分区存储管理有了深刻的理解,但是过程中遇到了很多困难,一边做一边学,对c++有了比较多的理解。 实验中遇到很多问题,浪费了很多时间,总而言之是自己学习还不够好,不扎实,希望在以后学习中加以改善,学到更多知识。 参考文献 【1】 汤子瀛,哲凤屏,汤小丹.计算机操作系统.西安:西安电子科技大学出版社,2001.。湖北民族学院信息工程学院11级计算机专业操作系统课程设计 【2】 任爱华.操作系统实用教程.北京:清华大学出版社,2001。 长春理工大学 软件学院 0813111班 27号 姓名:丁为胜 一. 概述 1、课程设计目的及任务课程设计地点及要求 每个学生一台微机,需要安装windows98或windows2000操作系统,配备VC、VB、java或C编程语言,每个学生上机时间不少于24个小时。 操作系统是计算机专业的核心专业课,“操作系统课程设计”是理解和巩固操作系统基本理论、原理和方法的重要的实践环节。 操作系统课程主要讲述的内容是多道操作系统的原理与技术,与其它计算机原理、编译原理、汇编语言、计算机网络、程序设计等专业课程关系十分密切。本课程设计的目的综合应用学生所学知识,建立系统和完整的计算机系统概念,理解和巩固操作系统基本理论、原理和方法,掌握操作系统基本理论与管理方式。在算法基础上,解决实际的管理功能的问题,提高学生实际应用、编程的能力。 主要任务是实现操作系统和相关系统软件的设计,其中涉及进程创建,同步,进程间的通信,存储管理,文件系统等操作系统概念。 2.课程设计地点及要求 每个学生一台微机,需要安装windows98或windows2000操作系统,配备VC、VB、java或C编程语言,每个学生上机时间不少于24个小时。 3.课程设计的内容 设计二: 设计任务: 掌握进程的管道通讯机制和信号量同步互斥机制。1. 进程的管道通讯 编制一个程序,程序中创建一个子进程。然后父子进程各自独立运行,父进程不断地在标准输入设备上读入小写字母,写入管道。子进程不断地从管道中读取字符,转换为大写字母后输出到标准输出设备上。当读到x时,结束。 2. 信号量实现的同步互斥机制 编制一个程序,程序中创建5个子进程,代表五位哲学家,然后父进程结束。使用信号量机制解决哲学家进餐问题。当哲学家进餐时,屏幕输出: [进程号] eating!当哲学家思考时,屏幕输出: [进程号] thinging!相关的系统调用和函数:pipe();write();read();semget();sepop();semctl();要求:查找并阅读上述系统调用的相关资料,将上述相关的函数封装为P()、V()操作,使用你封装的P()、V()操作实现5位哲学家的同步和互斥。 二. 设计的基本概念和原理 1.进程的管道通讯 管道(Pipe)实际是用于进程间通信的一段共享内存,创建管道的进程称为管道服务器,连接到一个管道的进程为管道客户机。命名管道(Named Pipes)是在管道服务器和一台或多台管道客户机之间进行单向或双向通信的一种命名的管道。一个命名管道的所有实例共享同一个管道名,但是每一个实例均拥有独立的缓存与句柄,并且为客户——服务通信提供有一个分离的管道。实例的使用保证了多个管道客户能够在同一时间使用同一个命名管道。 2.信号量实现的同步互斥机制 规定奇数号的哲学家先拿起他左边的筷子,然后再去拿他右边的筷子;而偶数号 的哲学家则相反.按此规定,将是1,2号哲学家竞争1号筷子,3,4号哲学家竞争3号筷子.即 五个哲学家都竞争奇数号筷子,获得后,再去竞争偶数号筷子,最后总会有一个哲学家能获 得两支筷子而进餐。而申请不到的哲学家进入阻塞等待队列,根FIFO原则,则先申请的哲 学家会较先可以吃饭,因此不会出现饿死的哲学家。 三. 总体设计 1.实现的方法和主要技术路线 1.无名管道 无名管道用于具有亲缘关系的父子进程,子子进程之间的通讯。它的实现函数有 int pipe(int fd[2]); //fd[2] 为描述符数组,包含一个读描述符与一个写描述符,在使用管道通信时,关闭某些不需要的读或写描述符,建立起单向的读或写管道,然后用read 和write 像操作文件一样去操作它即可。 如图便是进程1 到进程2 的一个读管道。 分别在父进程和父子进程里向管道写数据,然后在子进程和子子进程里读数据。2.哲学家进餐伪码: semaphore chopstick[5]={1,1,1,1,1};void philosopher(int i){ while(true){ think(); if(i%2 == 0)//偶数哲学家,先右后左。 { wait(chopstick[ i + 1 ] mod 5);wait(chopstick[ i]);eat(); signal(chopstick[ i + 1 ] mod 5);signal(chopstick[ i]);} Else //奇数哲学家,先左后右。 { wait(chopstick[ i]); wait(chopstick[ i + 1 ] mod 5);eat(); signal(chopstick[ i]); signal(chopstick[ i + 1 ] mod 5);} } 四. 详细设计 进程的管道通信代码: import java.io.IOException;import java.io.PipedReader; public class ReceiverThread1 extends Thread { PipedReader pipedReader; public ReceiverThread1(SenderThread1 sender)throws IOException { pipedReader=new PipedReader(sender.getPipedWriter()); } public void run() { char[] ch=new char[100];StringBuffer sb=null;String str=null;int i=0;try { while((i=pipedReader.read(ch))!=-1) { sb=new StringBuffer(); for(int j=0;j { sb.append(ch[j]); } str=sb.toString(); System.out.println(“子进程读取的字符为:”+str.toUpperCase()); if(!str.endsWith(“x”)) { System.out.print(“父进程读入字符为:”); }else if(str.endsWith(“x”)) { System.out.println(“结束无法再次输入字符”); } } } catch(IOException e){ e.printStackTrace();}finally{ try { pipedReader.close(); } catch(IOException e){ e.printStackTrace(); } } } } import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PipedWriter; public class SenderThread1 extends Thread { PipedWriter pipedWriter; public SenderThread1(){ pipedWriter=new PipedWriter();} public PipedWriter getPipedWriter(){ return pipedWriter;} public void run() { BufferedReader ir=new BufferedReader(new InputStreamReader(System.in));char[] ch=new char[100];StringBuffer sb=null;String str=null;int i=0;System.out.print(“父进程读入字符为:”);try { while((i=ir.read(ch))!=-1) { sb=new StringBuffer(); for(int j=0;j { if(ch[j]>='a' && ch[j]<='z') { sb.append(ch[j]); if(ch[j]=='x') { break; } } } str=sb.toString(); pipedWriter.write(str); if(str.startsWith(“x”)||str.endsWith(“x”)) { break; // this.stop(); } } } catch(IOException e){ e.printStackTrace();}finally{ try { ir.close(); pipedWriter.close(); } catch(IOException e){ e.printStackTrace(); } } } } public class ThreadComm1 { public static void main(String[] args)throws Exception{ SenderThread1 sender=new SenderThread1();ReceiverThread1 receiver=new ReceiverThread1(sender);sender.start();receiver.start();} } 哲学家进餐问题代码: #include “stdafx.h” using namespace std;bool chop[100];//定义筷子 class ph { protected: bool * left,* right;//哲学家的左右手指向的筷子 int eattime;//哲学家的吃饭时间 public: bool check()//用于检查哲学家左右手的筷子是不是被占用 { if(*left && *right) return true; else return false;} void eat(int ineattime)//哲学家开始进餐 { eattime=ineattime; *left=false; *right=false;} bool finish()//检查哲学家是否完成进餐 { if(eattime>0)//没完成的话剩余时间减少 { eattime--; if(eattime==0)//完成的话归还筷子 { *left=true; *right=true; return true; } else return false; } else return false;} void init(int num,int max)//初始化哲学家,指定他们使用的筷子 { eattime=0; left=&chop[num]; if(num right=&chop[num+1]; else right=&chop[0];} };void main(){ system(“title 哲学家进餐问题”);int in,i,temp,time,j=1;queue for(int i=0;i<5;i++){ chop[i]=1; } for(int i=0;i<5;i++){ P[i].init(i,5);} cout<<“输入哲学家进餐队列:”< break;else if(in>5) { cout<<“一共只有”<<5<<“个人!”< } else { Q.push(in-1); } } cout<<“每个人吃饭时间:”< P[temp].eat(time); cout< if(temp+2>5) cout<<1< else cout< Q.push(temp);} for(i=0;i<5;i++) { if(P[i].finish()) cout< } //Q.push(-1); for(i=0;i { temp=Q.front(); Q.pop(); //if(temp!=-1) { cout< Q.push(temp); } //else { // Q.pop(); break; } } } for(int j=0;j第四篇:操作系统课程设计
第五篇:操作系统课程设计