计算机操作系统 课程设计报告(推荐)_计算机系课程设计报告
计算机操作系统 课程设计报告(推荐)由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“计算机系课程设计报告”。
操作系统课程设计报告
时间:2010-12-20~2010-12-31 地点:信息技术实验中心
计算机科学与技术专业 2008级2班15号
杨 烨
2010-12-31
信息工程学院计算机科学与技术082班
目录
一、课程设计的目的和意义...........................................................................................................2
二、进程调度算法模拟...................................................................................................................21、设计目的.............................................................................................................................22、设计要求.............................................................................................................................23、时间片轮转算法模拟.........................................................................................................3
实现思想:.......................................................................................................................3(1)流程图.....................................................................................................................3(2)程序代码.................................................................................................................3(3)运行结果.................................................................................................................54、先来先服务算法模拟.........................................................................................................6 算法思想...................................................................................................................................6
(1)流程图.....................................................................................................................7(2)程序代码.................................................................................................................7(3)运行结果...............................................................................................................11
三、主存空间的回收与分配.........................................................................................................111、设计目的...........................................................................................................................112、设计要求...........................................................................................................................123、模拟算法的实现...............................................................................................................13(1)流程图...................................................................................................................13(2)程序代码...............................................................................................................13(3)运行结果...............................................................................................................28
四、模拟DOS文件的建立和使用...............................................................................................28设计目的.............................................................................................................................28 2 设计要求.............................................................................................................................283、模拟算法实现...................................................................................................................31(1)流程图...................................................................................................................31(2)程序代码...............................................................................................................31(3)运行结果...............................................................................................................36
五、磁盘调度算法模拟.................................................................................................................36
1.设计目的..............................................................................................................................36 2.实验原理..............................................................................................................................37 3.设计要求...........................................................................................................................374、模拟算法的实现...............................................................................................................38(1)各算法流程图.......................................................................................................38(2)程序代码...............................................................................................................39(3)运行结果...............................................................................................................45
六、总结.........................................................................................................................................45
信息工程学院计算机科学与技术082班
一、课程设计的目的和意义
本次操作系统课程设计的主要任务是进行系统级的程序设计。本课程设计是操作系统原理课程的延伸。通过该课程设计,使学生更好地掌握操作系统各部分结构、实现机理和各种典型算法,加深对操作系统的设计和实现思路的理解,培养学生的系统设计和动手能力,学会分析和编写程序。课程设计的实施将使学生在以下几个方面有所收获:
(1)加深对操作系统原理的理解,提高综合运用所学知识的能力;
(2)培养学生自主查阅参考资料的习惯,增强独立思考和解决问题的能力;(3)通过课程设计,培养严谨的科学态度和协作精神。
二、进程调度算法模拟
1、设计目的(1)要求学生设计并实现模拟进程调度的算法:时间片轮转及先来先服务。(2)理解进程控制块的结构。(3)理解进程运行的并发性。(4)掌握进程调度算法。
2、设计要求
在多道程序运行环境下,进程数目一般多于处理机数目,使得进程要通过竞争来使用处理机。这就要求系统能按某种算法,动态地把处理机分配给就绪队列中的一个进程,使之运行,分配处理机的任务是由进程调度程序完成的。一个进程被创建后,系统为了便于对进程进行管理,将系统中的所有进程按其状态,将其组织成不同的进程队列。于是系统中有运行进程队列、就绪队列和各种事件的进程等待队列。进程调度的功能就是从就绪队列中挑选一个进程到处理机上运行。进程调度的算法有多种,常用的有优先级调度算法、先来先服务算法、时间片轮转算法。
进程是程序在处理机上的执行过程。进程存在的标识是进程控制块(PCB),进程控制块结构如下:
typedef struct node { char name[10];/* 进程标识符 */ int prio;/* 进程优先数 */ int round;/* 进程时间轮转时间片 */ int cputime;/* 进程占用 CPU 时间*/ int needtime;/* 进程到完成还需要的时间*/ int count;/* 计数器*/ char state;/* 进程的状态*/ struct node *next /*链指针*/ }PCB;系统创建一个进程,就是由系统为某个程序设置一个PCB,用于对该进程进行控制和管
信息工程学院计算机科学与技术082班
理,进程任务完成,由系统收回其PCB,该进程便消亡。每个进程可以有三个状态:运行状态、就绪状态和完成状态。
用C语言、C++或者Java语言编写一个程序实现进程调度的算法,模拟进程调度的过程,加深对进程控制块概念和进程调度算法的理解。
本任务要求完成时间片轮转及先来先服务两个算法。
3、时间片轮转算法模拟
实现思想:
每次调度时,系统吧处理机分配给队列首进程让器执行一个时间片,当执行的时间片用完时,由一个计时器发出时钟中断请求,调度根据这个请求停止该进程的运行将其送到就绪队列的末尾,再把处理机分给就绪队列中新的队首进程,同时让它执行一个时间片。(1)流程图
进程调度—时间片轮转开始输入进程总数输入各进程信息更新在运行的进程的已运行时间输出为就绪状态的进程信息N输出此时为就绪状态的进程信息当前进程是否运行结束是否存在下个进程Y指向下一个进程YN结束跳过
(2)程序代码
#include #include using namespace std;typedef struct PNode {
// PCB
struct PNode *next;// 定义指向下一个节点的指针
char name[10];
// 定义进程名,并分配空间
信息工程学院计算机科学与技术082班
int All_Time;
// 定义总运行时间
int Runed_Time;
// 定义已运行时间
char state;
// 定义进程状态 Ready / End } * Proc;// 指向该PCB的指针 int ProcNum;// 总进程个数
void InitPCB(Proc &H)// 初始化就绪队列
{
cout
cin>>ProcNum;// 进程总个数
int Num=ProcNum;
H=(Proc)malloc(sizeof(PNode));// 建立头节点
H->next=NULL;
Proc p=H;//定义一个指针
cout
while(Num--){
p=p->next=(Proc)malloc(sizeof(PNode));
cout
cin>>p->name>>p->All_Time>>p->Runed_Time;
p->state='R';
p->next=NULL;}
p->next=H->next;
} void DispInfo(Proc H)//输出运行中的进程信息 {
Proc p=H->next;
do {
if(p->state!= 'E')
//如果该进程的状态不是End的话
{
coutnameAll_Time
Runed_Time
state
p=p->next;
}
else p=p->next;
}
} void SJP_Simulator(Proc &H)// 时间片轮转法 { while(p!= H->next);// 整个进程链条始终完整,只是状态位有差异
信息工程学院计算机科学与技术082班
cout
int flag=ProcNum;// 记录剩余进程数
int round=0;// 记录轮转数
Proc p=H->next;
while(p->All_Time > p->Runed_Time)
{
// 即未结束的进程
round++;
coutname
p->Runed_Time++;
// 更改正在运行的进程的已运行时间
DispInfo(H);
// 输出此时为就绪状态的进程的信息
if(p->All_Time == p->Runed_Time){
// 并判断该进程是否结束
p->state='E';
flag--;
coutname
}
p=p->next;
while(flag && p->All_Time == p->Runed_Time)
p=p->next;// 跳过先前已结束的进程 } cout
Proc H;
InitPCB(H);// 数据初始化
DispInfo(H);// 输出此刻的进程状态
SJP_Simulator(H);// 时间片轮转法
system(“pause”);}(3)运行结果
输入相关进程信息:
输出相关运行结果:
信息工程学院计算机科学与技术082班
4、先来先服务算法模拟 算法思想
按照进程的某种顺序进行排序,然后按照这个顺序进行调度。例如:可以按照作业提交时间或进程变为就绪状态的先后次序来分派处理器,让排在后面的进程占用处理器,知道该进程执行完或者由于某种原因被阻塞才让出处理器。
在该调度策略中还规定,当有一个事件发生(如一个I/O操作完成)时,会有一些进程被唤醒,这些被唤醒的进程并不能立即恢复执行,而是要等到当前运行的进程出让处理器后才可以被调度执行。采用此算法存在以下几个特点:
周转时间:对进程i来说,假设Tei是进程的完成时间,Tsi是进程的提交时间,那么进程i的周转时间Ti=进程完成时间-进程提交时间;
进程平均周转时间:T=1/nETi;
进程带权周转时间=进程等待时间+进程运行时间。
信息工程学院计算机科学与技术082班
(1)流程图
Begin输入当前磁道号now磁头移动距离sum=abs(now-array[0])磁头移动总距离sum+=abs(array[j]-array[i])输出磁盘调度序列array[j]目前位置编程当前的位置i++j
(2)程序代码
#include “stdio.h” #include #include
#define getpch(type)(type*)malloc(sizeof(type))#define NULL 0
struct pcb { /* 定义进程控制块PCB */ char name[10];char state;int super;
信息工程学院计算机科学与技术082班
int ntime;int rtime;struct pcb* link;}*ready=NULL,*p;typedef struct pcb PCB;
void sort()/* 建立对进程进行优先级排列函数*/ {
PCB *first, *second;int insert=0;
if((ready==NULL)||((p->super)>(ready->super)))/*优先级最大者,插入队首*/ {
p->link=ready;ready=p;}
else /* 进程比较优先级,插入适当的位置中*/ {
first=ready;second=first->link;while(second!=NULL){
if((p->super)>(second->super))/*若插入进程比当前进程优先数大,*/ { /*插入到当前进程前面*/ p->link=second;first->link=p;second=NULL;insert=1;}
else /* 插入进程优先数最低,则插入到队尾*/ {
first=first->link;second=second->link;} }
if(insert==0)first->link=p;} }
void input()/* 建立进程控制块函数*/ { int i,num;
printf(“n 请输入进程数:”);scanf(“%d”,&num);for(i=0;i
信息工程学院计算机科学与技术082班
printf(“n 进程号No.%d:n”,i+1);p=getpch(PCB);printf(“n 输入进程名:”);scanf(“%s”,p->name);printf(“n 输入进程优先数:”);scanf(“%d”,&p->super);printf(“n 输入进程运行时间:”);scanf(“%d”,&p->ntime);printf(“n”);
p->rtime=0;p->state='w';p->link=NULL;
sort();/* 调用sort函数*/ } } int space(){
int l=0;PCB* pr=ready;while(pr!=NULL){ l++;pr=pr->link;} return(l);}
void disp(PCB * pr)/*建立进程显示函数,用于显示当前进程*/ {
printf(“n qname t state t super t ndtime t runtime n”);printf(“|%st”,pr->name);printf(“|%ct”,pr->state);printf(“|%dt”,pr->super);printf(“|%dt”,pr->ntime);printf(“|%dt”,pr->rtime);printf(“n”);}
void check()/* 建立进程查看函数 */ { PCB* pr;
printf(“n **** 当前正在运行的进程是:%s”,p->name);/*显示当前运行进程*/ disp(p);pr=ready;
printf(“n ****当前就绪队列状态为:n”);/*显示就绪队列状态*/ while(pr!=NULL){
信息工程学院计算机科学与技术082班
disp(pr);pr=pr->link;} }
void destroy()/*建立进程撤消函数(进程运行结束,撤消进程)*/ {
printf(“n 进程 [%s] 已完成.n”,p->name);free(p);}
void running()/* 建立进程就绪函数(进程运行时间到,置就绪状态*/ {
(p->rtime)++;
if(p->rtime==p->ntime)
destroy();/* 调用destroy函数*/ else {
(p->super)--;p->state='w';
sort();/*调用sort函数*/ } } int
main()/*主函数*/ {
int len,h=0;char ch;input();len=space();
while((len!=0)&&(ready!=NULL)){
ch=getchar();h++;
printf(“n The execute number:%d n”,h);p=ready;ready=p->link;p->link=NULL;p->state='R';check();running();
printf(“n 按任一键继续......”);ch=getchar();}
printf(“nn 进程已经完成.n”);
信息工程学院计算机科学与技术082班
ch=getchar();}(3)运行结果
输入相关进程信息:
输出相关运行结果:
三、主存空间的回收与分配
1、设计目的主存是中央处理器能直接存取指令和数据的存储器,能否合理地利用主存,在很大程度
信息工程学院计算机科学与技术082班
上将影响到整个计算机系统的性能。主存分配是指在多道作业和多进程环境下,如何共享主存空间。主存回收是指当作业执行完毕或进程运行结束后将主存空间归还给系统。主存分配与回收的实现是与主存储器的管理方式有关。本次设计主要是为了帮助学生深入理解主存空间的分配与回收的几种算法。
(1)掌握最先适应分配算法(2)掌握最优适应分配算法(3)掌握最坏适应分配算法
2、设计要求
用户提出内存空间请求,系统根据申请者要求,按照最先适应分配算法的分配策略分析内存空间的使用情况,找出能满足请求的空闲区,分给申请者,当程序执行完毕时,系统要收回它所占用的内存空间。建立空闲数据文件,空闲区数据文件包括若干行,每行有两个字段:起始地址、内存块大小(均为整数),各字段以逗号隔开。下面是一个空闲区数据文件的示例:
0,10 10,08 18,10 28,06 34,10 44,09 读取空闲区数据文件,建立空闲区表并在屏幕上显示空闲内存状态,空闲区表记录了可供分配的空闲内存的起始地址和大小,用标志位指出该分区是否是未分配的空闲区。
接收用户的内存申请,格式为:作业名、申请空间的大小。
按照内存分配算法中的一种方法选择一个空闲区,分割并分配,修改空闲区表,填写内存已分配区表(起始地址、长度、标志位),其中标志位的一个作用是指出该区域分配给哪个作业。
进程结束后回收内存。空闲区表的结构如下:
typedef struct node{ int start;int length;char tag[20];}job;本次设计要求完成如下算法:
(1)设计一个内存分配回收的程序使用最先适应分配算法(2)设计一个内存分配回收的程序使用最优适应分配算法(3)设计一个内存分配回收的程序使用最坏适应分配算法 用户提出内存空间请求,系统根据申请者要求,选择上述算法的一种分配策略分析内存空间的使用情况,找出合适的空闲区,分给申请者,当进程执行完毕时,系统收回它所占用的内存空间。
信息工程学院计算机科学与技术082班
3、模拟算法的实现
(1)流程图
内存分配开始划定内存总量输入进程信息所需内存
(2)程序代码
#include #include #define LEN sizeof(struct area)#define LEN_POINTER_LIST sizeof(struct AreaPointer_list)struct area{
};//分区指针的链表
//当把空闲分区链表和占用分区链表按照地址先后顺序合并 //以显示整个内存情况的时候使用 struct AreaPointer_list{ struct area * data;struct AreaPointer_list * next;int start;//分区的其始地址 int length;//分区的长度 int job;//若被作业占用值为作业号,若空闲值为0 struct area * next;
信息工程学院计算机科学与技术082班
};struct area * idle;struct area * used;
//全局变量,空闲分区链表头指针 //全局变量,占用分区链表头指针
struct AreaPointer_list * whole = NULL;//全局变量,分区指针链表头指针 //p(previcious)n(next)指出在链表中的何处插入新生成的元素 //p==NULL 在链表头插入,返回头指针
//p!=NULL 在链表中或链表尾插入,返回当前插入的元素的指针 struct area * insert(int s,int l,int j,struct area * p,struct area * n){
} //此模块居于次要地位,只被使用一次 //打印分区链表
void print(struct area * head){
if(head == NULL){ } else{
while(head!= NULL){
if(head->job == 0)else
printf(“begin:%dKtlength:%dKtuse:Job%dt|n”,head->start,head->length,hea
printf(“begin:%dKtlength:%dKt空闲tt|n”,head->start,head->length);printf(“Area list is null...n”);struct area * current =(struct area *)malloc(LEN);current->start = s;current->length = l;current->job = j;if(p == NULL){//在链表头插入
} else{
} if(p->next == NULL){//在链表尾插入
} else{//在链表中插入
} return current;current->next = p->next;p->next = current;current->next = NULL;p->next = current;current->next = n;return current;
d->job);
信息工程学院计算机科学与技术082班
} void file_print(struct area * head,FILE * file){
if(head == NULL){ } else{
while(head!= NULL){
if(head->job == 0)else
fprintf(file,“begin:%dKtlength:%dKtuse:Job%dt|n”,head->start,head->length,fprintf(file,“begin:%dKtlength:%dKt空闲tt|n”,head->start,head->length);fprintf(file,“Area list is null...n”);
} } head = head->next;
head->job);
} //打印分区链表
} } head = head->next;//释放分区链表空间
void free_AreaList(struct area * head){
} //释放分区链表空间 //在分区链表中搜索插入位置
//flag==0 表明分区链表按起始地址从小到大排列 //flag==1 表明分区链表按分区长度从小到大排列 //输入参数 element 不能为NULL struct area * search_pos(struct area * element,struct area * head,int flag){
struct area * p = NULL;while(head!= NULL){
if(flag == 0){ if(element->start start)struct area * temp;while(head!= NULL){
} temp = head;head = head->next;free(temp);
信息工程学院计算机科学与技术082班
} //返回值p==NULL表明插入位置在链表头 //返回值p!=NULL表明插入位置在p 之后 //进行分区链表的实际插入工作
//flag==0 表明分区链表按起始地址从小到大排列 //flag==1 表明分区链表按分区长度从小到大排列 //输入参数 element->next 要为NULL struct area * insert_list(struct area * element,struct area * list,int flag){
if(list == NULL)else{
} return list;struct area * pos = search_pos(element,list,flag);if(pos == NULL){
} else{
} element->next = pos->next;pos->next = element;element->next = list;list = element;list = element;
} return p;} else {
} p = head;head = head->next;if(element->length length)
break;
break;}//返回插入元素之后新链表的头指针
//进行查询空闲分区链表动态分配分区的实际工作,算法步骤:
//1。查询空闲分区链表中是否有长度大于或等于申请长度的分区,若没有返回FALSE //2。若查找到符合条件的分区,把它从空闲链表中取出
//3。根据请求把取出的空闲分区分块,把新的占用分区和剩余空闲分区分别插入链表
//注意:插入占用分区链表按照固定的地址先后顺序,插入空闲分区链表的方式要根据flag的值 int memory_alloc(int length,int job,int flag){ struct area * used_element;
信息工程学院计算机科学与技术082班
struct area * free_element;struct area * head = idle;struct area * head_temp = used;struct area * p = NULL;//检测输入的作业号是否存在 while(head_temp!= NULL){
} //在空闲分区链表中查找 while(head!= NULL){
} if(head!= NULL){
} else return 0;//生成新的占用区链表元素并插入占用区链表 used_element =(struct area *)malloc(LEN);used_element->start = head->start;used_element->length = length;used_element->job = job;used_element->next = NULL;used = insert_list(used_element,used,0);//若空闲分区分块后有剩余,生成新的空闲区链表元素并插入空闲区链表 if(head->length > length){ free_element =(struct area *)malloc(LEN);//从空闲区链表中取出
if(p == NULL)//链表中的第一个分区符合条件 { } else { } head->next = NULL;p->next = head->next;idle = idle->next;if(head->length >= length)break;p = head;head = head->next;if(head_temp->job == job)return 2;head_temp = head_temp->next;
信息工程学院计算机科学与技术082班
} //进行查询占用分区链表动态释放分区的实际工作,算法步骤:
//1。根据作业号查询到占用分区链表中要释放的分区,若没有返回FALSE //2。若查找到要释放的分区,把它从空闲链表中取出 //3。根据取出的分区的数据建立新的空闲分区
//4。在空闲分区链表中查询是否有和新空闲分区相邻的空闲分区,有则合并 //5。根据flag的取值按照特定方式插入空闲分区链表 int memory_free(int job,int flag){
struct area * used_element;struct area * free_element;struct area * head = used;struct area * p = NULL;struct area * previcious1 = NULL;struct area * current1 = NULL;struct area * previcious2 = NULL;struct area * current2 = NULL;//根据作业号在占用分区链表中查找 while(head!= NULL){
} if(head!= NULL){
//从占用区链表中取出
if(p == NULL)//链表中的第一个分区符合条件 { } else { used = used->next;if(head->job == job)break;p = head;head = head->next;
} //释放空间 free(head);return 1;free_element->start = head->start + length;free_element->length = head->length-length;free_element->job = 0;free_element->next = NULL;idle = insert_list(free_element,idle,flag);
信息工程学院计算机科学与技术082班
} else return 0;//建立新的空闲分区 used_element = head;free_element =(struct area *)malloc(LEN);free_element->start = used_element->start;free_element->length = used_element->length;free_element->job = 0;free_element->next = NULL;//从空闲区链表查找和新的空闲分区相邻分区 head = idle;p = NULL;while(head!= NULL){
} //合并相邻空闲分区 if(current1!= NULL){
} //把和新分区相邻的分区从空闲分区链表中取出 if(previcious1 == NULL)else previcious1->next = current1->next;current1->next = NULL;//修改新空闲分区的相关数据 free_element->start = current1->start;free_element->length = free_element->length + current1->length;idle = idle->next;if(head->start + head->length == used_element->start){
} if(used_element->start + used_element->length == head->start){
} p = head;head = head->next;previcious2 = p;current2 = head;previcious1 = p;current1 = head;} head->next = NULL;p->next = head->next;
信息工程学院计算机科学与技术082班
} //和分区指针链表相关的操作,用来合并空闲分区链表和占用分区链表,保存链表元素的指针 struct AreaPointer_list * search_position(int s,struct AreaPointer_list * head){
} struct AreaPointer_list * emerge(struct area * idle_temp,struct area * used_temp){
struct AreaPointer_list * previcious;struct AreaPointer_list * temp;
if(used_temp!= NULL){
whole =(struct AreaPointer_list *)malloc(LEN_POINTER_LIST);whole->data = used_temp;whole->next = NULL;previcious = whole;used_temp = used_temp->next;while(used_temp!= NULL){ temp =(struct AreaPointer_list *)malloc(LEN_POINTER_LIST);struct AreaPointer_list * p = NULL;while(head!= NULL){
} return p;if(s data)->start)break;p = head;head = head->next;if(current2!= NULL){
} //根据flag的取值按照特定方式插入空闲分区链表 idle = insert_list(free_element,idle,flag);//释放空间 free(used_element);return 1;//把和新分区相邻的分区从空闲分区链表中取出 if(previcious2 == NULL)else previcious2->next = current2->next;current2->next = NULL;//修改新空闲分区的相关数据
free_element->length = free_element->length + current2->length;idle = idle->next;
信息工程学院计算机科学与技术082班
} void printall(struct AreaPointer_list * head){
struct area * data_temp;if(head == NULL)else{
while(head!= NULL){
data_temp = head->data;if(data_temp->job == 0)else
printf(“begin:%dKtlength:%dKt空闲tt|n”,data_temp->start,data_temp->lenprintf(“Area pointer list is null...n”);
} while(idle_temp!= NULL){
} return whole;struct area * idle_next = idle_temp->next;struct AreaPointer_list * pos = search_position(idle_temp->start,whole);if(pos == NULL){
} else {
} idle_temp = idle_next;temp =(struct AreaPointer_list *)malloc(LEN_POINTER_LIST);temp->data = idle_temp;temp->next = pos->next;pos->next = temp;temp =(struct AreaPointer_list *)malloc(LEN_POINTER_LIST);temp->data = idle_temp;temp->next = whole;whole = temp;
} temp->data = used_temp;temp->next = NULL;previcious->next = temp;previcious = temp;used_temp = used_temp->next;
gth);
printf(“begin:%dKtlength:%dKtuse:Job%dt|n”,data_temp->start,data_temp->length,data_temp->job);head = head->next;
信息工程学院计算机科学与技术082班
} void file_printall(struct AreaPointer_list * head,FILE * file){
struct area * data_temp;if(head == NULL)else{
while(head!= NULL){ data_temp = head->data;if(data_temp->job == 0)else
fprintf(file,“begin:%dKtlength:%dKt空闲tt|n”,data_temp->start,data_tempfprintf(file,“Area pointer list is null...n”);} }
->length);
fprintf(file,“begin:%dKtlength:%dKtuse:Job%dt|n”,data_temp->start,data_temp->length,data_temp->job);
} void free_PointerList(struct AreaPointer_list * head){
} //和分区指针链表相关的操作,用来合并空闲分区链表和占用分区链表,保存链表元素的指针 void input_by_hand(){
int job;int is_alloc;//1 申请分区 0 释放分区 int length;int flag;printf(“请选择分区分配算法:输入0---最先适配 输入1---最优适配n”);scanf(“%d”,&flag);while(flag!= 0 && flag!= 1){ printf(“数据输入错误,请参照提示重新输入n”);scanf(“%d”,&flag);struct AreaPointer_list * temp;while(head!= NULL){
} temp = head;head = head->next;free(temp);
} } head = head->next;
信息工程学院计算机科学与技术082班
} if(flag == 0)printf(“选择最先适配算法--->请输入请求队列数据:(输入 0 0 0 结束)n”);printf(“选择最优适配算法--->请输入请求队列数据:(输入 0 0 0 结束)n”);if(flag == 1)printf(“输入数据格式:作业号(int>0)[输入1--申请|输入0--释放] 分区长度(int>0)n”);printf(“例如输入 5 1 130 表示 作业5申请130Kn”);printf(“例如输入 3 0 200 表示 作业3释放200Kn”);while(1)//输入 0 0 0 结束 {
scanf(“%d%d%d”,&job,&is_alloc,&length);if(job == 0 && is_alloc == 0 && length == 0){
} if(is_alloc == 1){
} if(is_alloc == 0){
int r = memory_free(job,flag);if(!r){ int r = memory_alloc(length,job,flag);if(!r){
} if(r == 2){
}
printf(“n”);
printf(“输入作业号已存在于占用分区链表,请重新输入...n”);printf(“n”);continue;printf(“n”);
printf(“没有符合条件的空闲分区可供分配,请等待释放...n”);printf(“n”);continue;printf(“数据输入错误,请参照提示重新输入n”);scanf(“%d%d%d”,&job,&is_alloc,&length);if(job == 0 && is_alloc == 0 && length == 0)
return;break;while(job
信息工程学院计算机科学与技术082班
} /*void input_by_file(int flag){
int job;int is_alloc;//1 申请分区 0 释放分区 int length;char* result;int r;FILE * file1;FILE * file2;if(flag == 0)else result = “result_data_2.txt”;result = “result_data_1.txt”;
} //释放空间 free_AreaList(idle);free_AreaList(used);idle = NULL;used = NULL;
} emerge(idle,used);printf(“n”);printf(“------------------n”);printf(“空闲分区链表:ttttt|n”);print(idle);printf(“tttttt|n”);printf(“占用分区链表:ttttt|n”);print(used);printf(“tttttt|n”);printf(“整个内存情况:ttttt|n”);printf(“低地址tttttt|n”);printall(whole);printf(“高地址tttttt|n”);printf(“------------------n”);printf(“n”);free_PointerList(whole);whole = NULL;
}
printf(“n”);
printf(“没有与指定作业号符合的占用分区,请重新输入...n”);printf(“n”);continue;
信息工程学院计算机科学与技术082班
if((file1 = fopen(“source_data.txt”,“r”))== NULL){
} if((file2 = fopen(result,“w”))== NULL){
} if(flag == 0){
} else {
} while(!feof(file1)){
fscanf(file1,“%d%d%d”,&job,&is_alloc,&length);if(job
} if(is_alloc == 1){
printf(“JOB %d申请%dKnn”,job,length);fprintf(file2,“JOB %d申请%dKnn”,job,length);r = memory_alloc(length,job,flag);if(!r){
} if(r == 2){
printf(“输入作业号已存在于占用分区链表,不于处理nn”);
printf(“没有符合条件的空闲分区可供分配,不于处理nn”);fprintf(file2,“没有符合条件的空闲分区可供分配,不于处理nn”);continue;printf(“文件中数据%d %d %d输入的格式错误,不于处理nn”,job,is_alloc,lengtfprintf(file2,“文件中数据%d %d %d输入的格式错误,不于处理nn”,job,is_alloc,continue;printf(“按照最优分配算法得出的结果:nn”);fprintf(file2,“按照最优分配算法得出的结果:nn”);printf(“按照最先分配算法得出的结果:nn”);fprintf(file2,“按照最先分配算法得出的结果:nn”);printf(“不能打开source_data.txt文件...n”);exit(0);printf(“不能打开source_data.txt文件...n”);exit(0);
h);
length);
信息工程学院计算机科学与技术082班
} else {
} emerge(idle,used);printf(“------------------n”);fprintf(file2,“------------------n”);printf(“空闲分区链表:ttttt|n”);fprintf(file2,“空闲分区链表:ttttt|n”);print(idle);file_print(idle,file2);printf(“tttttt|n”);fprintf(file2,“tttttt|n”);printf(“占用分区链表:ttttt|n”);fprintf(file2,“占用分区链表:ttttt|n”);print(used);file_print(used,file2);printf(“tttttt|n”);fprintf(file2,“tttttt|n”);printf(“整个内存情况:ttttt|n”);fprintf(file2,“整个内存情况:ttttt|n”);printf(“低地址tttttt|n”);fprintf(file2,“低地址tttttt|n”);printall(whole);file_printall(whole,file2);printf(“高地址tttttt|n”);fprintf(file2,“高地址tttttt|n”);printf(“------------------n”);fprintf(file2,“------------------n”);printf(“n”);fprintf(file2,“n”);printf(“JOB %d释放%dKnn”,job,length);fprintf(file2,“JOB %d释放%dKnn”,job,length);r = memory_free(job,flag);if(!r){
}
printf(“没有与指定作业号符合的占用分区,不于处理nn”);fprintf(file2,“没有与指定作业号符合的占用分区,不于处理nn”);continue;
}
fprintf(file2,“输入作业号已存在于占用分区链表,不于处理nn”);continue;
信息工程学院计算机科学与技术082班
}*/ int main()
} { idle = insert(0,640,0,NULL,NULL);used = NULL;input_by_hand();
} printf(“========================================nn”);fprintf(file2,“========================================nn”);//释放空间 free_AreaList(idle);free_AreaList(used);idle = NULL;used = NULL;fclose(file1);fclose(file2);free_PointerList(whole);whole = NULL;
信息工程学院计算机科学与技术082班
(3)运行结果
四、模拟DOS文件的建立和使用设计目的磁盘文件是磁盘上存储的重要信息,通过本实验模拟DOS文件的建立和使用情况,理解磁盘文件的物理结构。文件管理是操作系统中重要的内容之一,不同的文件系统提供了不同的物理结构,通过实验,深入理解文件的物理结构与存取方法之间的关系,以便更好的掌握文件系统的概念。设计要求
模拟设计DOS操作系统中磁盘文件的存储结构
DOS操作系统对磁盘文件的管理采用链接结构,将所有的链接指针集中在一起,存放在文件分配表(FAT)中。连接文件的第一个物理块号登记在文件目录中。其设计思想是:假定磁盘上共有N个物理块可供使用,当要存放文件时,从FAT表中寻找其值为0的项,用其对应的物理块存放文件信息,并把文件占有的各物理块用链接指针登记在FAT表中,再把文
信息工程学院计算机科学与技术082班
件的第一个物理块号登记在文件目录中。
文件目录及FAT表如图所示:
在DOS中FAT表的前两项用来记录磁盘的类型。而从第2项开始记录磁盘的分配情况和文件各物理块的链接情况。在FAT表中第三项的值如果为0,表示对应的第三块空闲。由图还知道文件A的各记录依次存放在第2、第4、第15、第16、第50等六个物理块中。第50块中的指针为FFF,表示文件A的结束。文件B的各记录依次存放在第7、第10、第20等三个物理块中。第20块中的指针为FFF。
假定磁盘存储空间共有100个物理块,设计一个文件分配表。为了简单,文件分配表可用一个数组定义,其中每一个元素与一个物理块对应。当第 i 个元素为 0 时,表示第 i 块空闲;当第 i 个元素既不为 0 也不为 FFF 时,其值表示该文件的下一个物理块号。另外,再设一个空闲块总数变量记录系统还有的空闲块数。为了简单,假定一个物理块指存放一个逻辑记录,要求设计一个程序,把文件的逻辑记录结构转换成 DOS 的链接结构。当用户要求将已在主存的文件保存在磁盘上时,给出文件名及文件的记录个数,系统应能在磁盘上正确地保存文件。或当用户要求给指定文件增加记录时,也应正确的实现,并插在指定记录之后。
为了正确地执行模拟程序,可用键盘模拟输入用户的要求。输入格式为:
write(文件名,记录个数)或
insert(文件名,逻辑记录号)模拟设计便于直接存取的索引文件结构 为了便于用户直接存取文件的各个逻辑记录,在 MS-DOS 中通过文件目录,再沿着链查找FAT表,便可直接找到指定逻辑记录对应的物理块。在小型机或更高级的文件系统中,直接存取文件的方法是为每个文件建立一个索引表,指出各逻辑记录与物理块的对应关系。最简单的形式是一个逻辑记录对应一个物理块。文件目录与索引表的关系如图所示。
信息工程学院计算机科学与技术082班
通常索引表按照逻辑记录顺序建立,这样既有利于顺序存储,又有利于直接存储。为了标识哪些记录已经建立,哪些记录还没建立,故在索引表中增设一个标志位。写文件或插入一个记录的过程是寻找一个空闲物理块,然后将其填入索引表对应项中。其建立过程同第一题,即 write(文件名,记录号)和 insert(文件名,记录号)。
要求用位示图描绘出磁盘的使用情况,并要求模拟程序执行过程的每一步都能显示文件目录、位示图、索引表。
信息工程学院计算机科学与技术082班
3、模拟算法实现
(1)流程图
创建文件流程开始读取文件流程开始查询未打开的文件表查询已打开文件表在未打开表中?N是否在已打开的文件表里?YY是否在已打开表中查询剩余未打开的文件表NYY显示无文件是否在剩余表中?N输出无文件读取文件记录读取文件记录返回Read参数合法?Nwrite参数是否合法?Y返回写入磁盘显示参数非法显示成功Y显示参数非法根据参数读取记录并显示END
(2)程序代码
#include #include #include #include #include //#include using namespace std;const int FDF=-2;const int FFF=-1;const int N=100;//存储空间(FAT表长度)int fnum;//文件数量 struct FILEINFO{
};
char filename[10];int filestart;int filelength;
信息工程学院计算机科学与技术082班
FILEINFO file[10];int FAT[N],blankspace;//FAT表和剩余空间 void printfmenu(){
int i;cout
文件名
起始块号
文件长度“
} void write(char *tmpname,int tmplength){
int last,i,j;//复制文件名和文件块个数 strcpy(file[fnum].filename,tmpname);file[fnum].filelength=tmplength;//存文件 for(i=2;i
} for(i=1;i
for(j=2;j
FAT[last]=j;
if(FAT[i]==0){
} file[fnum].filestart=i;//首个空闲块为文件开始块 last=i;FAT[last]=FFF;break;int i;cout
} cout
信息工程学院计算机科学与技术082班
} void insert(char *tmpname,int insertpoint){
int i;int last,brpoint;//寻找要执行插入操作的文件,将其数组下标存入last for(i=0;i
} //brpoint记录当前文件扫描到的位置 brpoint=file[last].filestart;
for(i=0;i
} //改变空闲块个数与文件长度
if(FAT[i]==0){
} FAT[i]=FAT[brpoint];FAT[brpoint]=i;break;brpoint=FAT[brpoint];//扫描直到找到插入位置 if(strcmp(file[i].filename,tmpname)==0){
} else printf(”没有指定文件!n“);last=i;break;
} FAT[last]=FFF;//文件末存结束标记 blankspace-=tmplength;//改变空闲块个数 fnum++;cout
}
last=j;FAT[last]=FFF;break;
信息工程学院计算机科学与技术082班
} void itol(int i){ //LPCTSTR yy;char zz[10];file[last].filelength++;blankspace--;cout
//sprintf(zz, ”%d“, i);
//itoa(i,zz,10);
//yy = LPCTSTR(zz);
} void ctol(char *c){
} void Graph(){
int i,x=200,y=50;//initgraph(640, 480);//setfillstyle(SOLID_FILL,WHITE);//floodfill(5,5,WHITE);//setcolor(BLACK);for(i=0;i
} //getch();//closegraph();
//moveto(x+(i/20)*60-25,y+(i%20)*20);itol(i);//rectangle(x+(i/20)*60,y+(i%20)*20,x+(i/20)*60+30,y+(i%20)*20+20);//moveto(x+(i/20)*60,y+(i%20)*20);if(FAT[i]==FFF)ctol(”FFF“);ctol(”FDF“);else if(FAT[i]==FDF)else itol(FAT[i]);//LPCTSTR yy;//yy = LPCTSTR(c);//moverel(3,2);//outtext(yy);//moveto(x+i*2,y+20);//moverel(5,3);//outtext(yy);//return yy;
信息工程学院计算机科学与技术082班
}
void main(){
} int i;char tmpname[10];int tmplength;//要写入文件长度 int o;//命令 fnum=0;for(i=0;i
} FAT[0]=FDF;FAT[1]=FFF;FAT[3]=999;blankspace=98;while(1){
} printFAT();cin.get();cout>o;switch(o){
} case 1: cout
cin>>tmpname;
cout>tmplength;
write(tmpname,tmplength);break;cin>>tmpname;int insertpoint;
cout>insertpoint;
insert(tmpname,insertpoint);break;FAT[i]=0;case 2: cout
信息工程学院计算机科学与技术082班
(3)运行结果
五、磁盘调度算法模拟
1.设计目的(1)要求学生设计一个模拟磁盘调度的程序(2)理解磁盘调度过程中的三个时间段(3)理解磁盘调度的三种算法
信息工程学院计算机科学与技术082班
2.实验原理
共享设备的典型代表为磁盘,磁盘的物理块的地址由柱面号、磁道号、扇区号来指定,完成磁盘某一个物理块的访问要经过三个阶段:寻道时间 Ts、旋转延迟 Tw 和读写时间 Trw。
寻道时间 Ts 是磁头从当前磁道移动到目标磁道所需要的时间;旋转延迟 Tw 是当磁头停留在目标磁道后,目标物理块从当前位置旋转到磁头位置的时间;读写时间 Trw 是目标物理块内容与内存中对应交换的时间。磁盘调度的原则是公平和高吞吐量,衡量指标有访问时间 T 和平均访问时间 Ta:
T=Ts+Tw+Trw Ta=Tsa+Twa+Trwa 寻道时间和旋转延迟成为调度算法的主要考虑因素。减少访问时间就是要减少寻道时间和旋转延迟。
3.设计要求
(1)设计并实现一个函数,完成先来先服务的磁盘调度功能
(2)设计并实现一个函数完成最短寻道时间优先的磁盘调度功能。(3)设计并实现一个函数完成电梯算法的磁盘调度功能。
信息工程学院计算机科学与技术082班
4、模拟算法的实现
(1)各算法流程图
先来先服务算法
Begin输入当前磁道号now磁头移动距离Sum=abs(now-array[0])磁头总移动距离Sum+=abs(array[j]-array[i])输出磁盘调度序列Array[j]N目前的位置变为当前的位置j++J
信息工程学院计算机科学与技术082班
最短寻道时间优先算法流程图
Begin奖磁道从小到大排序输入当前磁道号nowArray[m-1]=now?磁头移动总距离Sum=now-array[i]输出磁盘调度序列array[j]确定当前磁道在已排的序列中的位置目前的位置变为当前的位置now=array[i]磁头移动的总距离Now-array[l]=0i
(2)程序代码
#include #include #include void FCFS(int array[],int m)// 先来先服务算法 {
int j,i,now;float sum = 0,avg;
cout
信息工程学院计算机科学与技术082班
cin>>now;sum=abs(now-array[0]);
cout
for(i=0,j=1;j
sum=sum+abs(array[j]-array[i]);
cout
//输出磁盘调度序列
}
avg=sum/(m);
cout
int temp;
int k=1;
int now,l,r;
int i,j;
float sum=0,avg=0;
for(i=0;i
for(j=i+1;j
{
if(array[i]>array[j])//将磁道号从小到大排序 {
temp=array[i];
array[i]=array[j];
array[j]=temp;
}
cout
cin>>now;
cout
if(array[m-1]
{
for(i=m-1;i>=0;i--)
{ cout
}
else
{ if(array[0]>=now)//若被访问的下一最小的磁道号不小于当前的磁道号 {
sum=now-array[i];
now=array[i];} }
信息工程学院计算机科学与技术082班
for(i=0;i
{ cout
sum=array[i]-now;
} } {
{ k++;
} now=array[i];
else //当前的磁道号的值在若所有被访问的下的磁道号之间
while(array[k]
l=k-1;
r=k;
if((now-array[l])
{
while(l>=0)
//先向磁道号减小方向访问
{ cout
sum=sum+now-array[l];
now=array[l];
l=l-1;
}
else
//先向磁道号增加方向访问
{
while(r
}
now=array[0];
for(j=r;j
{ cout
sum+=array[j]-now;
}
now=array[j];
{
cout
sum+=array[r]-now;
now=array[r];
r=r+1;
}
now=array[m-1];
for(j=l;j>=0;j--)//再向磁道号减小方向访问
{ cout
sum+=now-array[j];
}
now=array[j];
信息工程学院计算机科学与技术082班
}
avg=sum/(m);
cout
int temp;
int k=1;
int now,d,l,r;
int i,j;
float sum=0,avg=0;
for(i=0;i
for(j=i+1;j
{
if(array[i]>array[j])//将磁道号从小到大排序 {
temp=array[i];
array[i]=array[j];
array[j]=temp;
}
cout
cin>>now;
cout
cin>>d;
//先要给出当前磁道号和移动臂的移动方向
cout
if(array[m-1]
//若被访问的下一最大的磁道号不大于当前的磁道号
{
for(i=m-1;i>=0;i--)
{ cout
}
else
{ if(array[0]>=now)//若被访问的下一最小的磁道号不小于当前的磁道号 {
sum=now-array[i];
now=array[i];} }
} }
for(i=0;i
{ cout
sum=array[i]-now;
信息工程学院计算机科学与技术082班
} } {
{ k++;
} now=array[i];
else //当前的磁道号的值在若所有被访问的下的磁道号之间
while(array[k]
l=k-1;
r=k;
switch(d)
{
case 0:
//先向磁道号减小方向访问
{
while(l>=0)
{
cout
sum=sum+now-array[l];
now=array[l];
l=l-1;
{
while(r
}
now=array[0];
for(j=r;j
{ cout
sum+=array[j]-now;
} break;}
now=array[j];
case 1:
//先向磁道号增加方向访问
{
cout
sum+=array[r]-now;
now=array[r];
r=r+1;
}
now=array[m-1];
for(j=l;j>=0;j--)
{ cout
sum+=now-array[j];
}break;
now=array[j];
}
信息工程学院计算机科学与技术082班
}
avg=sum/(m);
cout
int i,m,n,flag=1,array[100];
cout
cin>>m;
cout>array[i];} do {
cout
cout
cout
cout
cout
} cin>>n;{
case 0: { flag=0;break;} //终止程序
case 1:
} { FCFS(array,m);break;} //先来先服务算法 { SSTF(array,m);break;}//最短寻道时间优先算法 { SCAN(array,m);break;}//电梯算法
case 2:
switch(n)
default: cout
} }
case 3:
default: cout
信息工程学院计算机科学与技术082班
(3)运行结果
输入相关调度信息:
先来先服务算法:
最短寻道时间优先算法:
电梯算法:
六、总结
本人在刘发升老师的指导下,顺利完成该课程设计。通过此次课程设计,收获颇多。
一、对实验原理有更深的理解 通过模拟DOS的课程设计,掌握了DOS各项功能实现的根本原理。并通过把该算法的内容,算法的执行顺序在计算机上实现,把原来以为很深奥的书本知识变的更为简单,对实验原理有更深的理解。
二、对该理论在实践中的应用有深刻的理解 通过把该算法的内容,算法的执行顺序在计算机上实现,知道和理解了该理论在计算机中是怎样执行的,对该理论在实践中的应用有深刻的理解。
三、激发了学习的积极性
信息工程学院计算机科学与技术082班
通过此次课程设计,全面系统的理解了计算机操作系统中各项功能的一般原理和基本实现方法。把死板的课本知识变得生动有趣,激发了学习的积极性。把学过的计算机操作系统的知识强化,能够把课堂上学的知识通过自己设计的程序表示出来,加深了对理论知识的理解。以前对与计算机操作系统的认识是模糊的,概念上的,现在通过自己动手做实验,从实践上认识了操作系统是如何处理命令的,如何协调计算机内部各个部件运行。课程设计中程序比较复杂,在调试时应该仔细,在程序调试时,注意指针,将不必要的命令去除。在这次课程设计中,我就是按照实验指导的思想来完成。加深了理解文件系统的内部功能及内部实现,培养实践动手能力和程序开发能力的目的。
四、理解了该知识点以及学科之间的融合渗透
本次课程设计程序部分是用C语言编写的,把《计算机操作系统》和《C语言》两门门学科联系起来,把各个学科之间的知识融合起来,把各门课程的知识联系起来,对计算机整体的认识更加深刻。使我加深了对《计算机操作系统》和《C语言》课程的认识。同时对操作系统中各种功能的本质有了充分地了解。