计算机操作系统课程设计报告

更新时间:2024-06-28 18:26:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

《操作系统原理》

实 验 报 告

院 (部): 管理工程学院 专 业:信息管理与信息系统 实验项目:实验一 二 三 五 班 级:信管102 姓 名:姚红叶 学 号:2010021411

目 录

引 言.......................................................................................................................... 3

实验目的: ............................................................................................................... 4 实验内容: ............................................................................................................... 4

实验步骤: ............................................................................................................... 4 实验代码: ............................................................................................................... 5 程序运行结果及分析 ................................................................................................10 实验二、模拟进程调度功能............................................................................................. 11

实验目的: .............................................................................................................. 11 实验内容: .............................................................................................................. 11 实验步骤: .............................................................................................................. 11 实验代码: ..............................................................................................................12 程序运行结果及分析 ................................................................................................16 实验三:模拟动态分区首次适应分配和回收算法 .............................................................17

实验目的: ..............................................................................................................17

实验内容: ..............................................................................................................17 实验步骤: ..............................................................................................................17 实验代码: ..............................................................................................................17 程序运行结果及分析 ................................................................................................24 实验五:模拟使用银行家算法判断系统的状态.................................................................25

实验目的: ..............................................................................................................25 实验步骤: ..............................................................................................................25 实验代码: ..............................................................................................................25 程序运行结果及分析 ................................................................................................30

2

引 言

操作系统是信息管理与信息系统专业一门重要的专业理论课程,了解和掌握操作系统的基本概念、功能和实现原理,对认识整个计算机系统的工作原理十分重要。

操作系统实验是操作系统课程的一个重要组成部分,通过试验环节的锻炼使同学们不仅能够对以前的所学过的基础知识加以巩固,同时能够通过上机实验,对操作系统的抽象理论知识加以理解,最终达到融会贯通的目的,因此,实验环节是同学们理解、掌握操作系统基本理论的一个重要环节。

本实验指导书,根据教材中的重点内容设定了相应的实验题目,由于实验课程的学时有限, 我们规定了必做题目和选做题目,其中必做题目必须在规定的上机学时中完成,必须有相应的预习报告和实验报告。选做题目是针对有能力或感兴趣的同学利用课余时间或上机学时的剩余时间完成

3

实验一、模拟进程创建、终止、阻塞、唤醒原语

实验目的:

通过设计并调试创建、终止、阻塞、唤醒原语功能,有助于对操作系统中进程控制功能的理解,掌握操作系统模块的设计方法和工作原理。

实验内容:

1、设计创建、终止、阻塞、唤醒原语功能函数。

2、设计主函数,采用菜单结构(参见后面给出的流程图)。

3、设计“显示队列”函数,目的能将就绪、阻塞队列中的进程信息显示在屏幕上,以供

随时查看各队列中进程的变化情况。

实验步骤:

1、进程PCB中应包含以下内容:

进程名 优先级 运行时间 状态 指针 2、系统总体结构:

系统主菜单 1?创建 2?阻塞 3?唤醒 4?终止 5?显示 0?退出 请输入您需要的功能(0-5):

其中:

进程名用P1,P2标识。

优先级及运行时间:为实验题目二做准备。 状态为:就绪、运行、阻塞,三种基本状态。 指针:指向下一个PCB。

开始 输入选择=? 0 1 2 3 4 5 4

退出 创建 阻塞 唤醒 终止

结束 实验代码:

#include #include struct PCB { char name[4]; int priority;

int runtime;

};

void main() { int x,t; int a=0;

int k=0,r=1,i=0,j=0;//k为就绪队列总数,r堵塞队列总数 char name[4];

struct PCB pcb[10];

struct PCB pcb1[10]; struct PCB pcb2[10]; printf(\菜单---------------------\\n\\n\\n\ printf(\退出系统\\n\ printf(\创建进程\\n\ printf(\堵塞进程\\n\ printf(\唤醒进程\\n\ printf(\终止进程\\n\

printf(\显示进程\\n\

printf(\ strcpy(pcb1[0].name,\堵塞队列 pcb1[0].priority = 2; pcb1[0].runtime = 3;

//printf(\ %d %d\

显示 5

实验二、模拟进程调度功能

实验目的:

通过本实验,进一步掌握进程调度的功能和实现原理。

实验内容:

1、 设计进程调度功能,至少模拟两种以上调度算法。如:优先级调度算法、时间片调度

算法等。

2、 进程调度功能作为一个函数scheduler,加入到实验题目一中。

3、 进程调度程序从就绪队列中挑选进程,若队列为空,应显示“无就绪进程无法调度”

的提示信息。

4、 若选上一个进程,以显示:进程名、状态、时间片、优先级等信息表示一个进程被执

行。若运行完,应删除相应PCB。

实验步骤:

1、 在实验题目一中的主菜单中加入一个菜单项:6 调度,选择该菜单项后,系统进入进程调度。 2、 进程调度的结构:

进程调度子菜单 0---------返回主菜单 1---------优先级调度 2---------时间片调度 请选择您需要的功能选项:

X=? = 0 = 2 = 1 返回上级菜单

转优先级调度算法 转时间片调度算法 11

读入选择=》x

实验代码:

#include #include void priority(); void time(); struct PCB { char name[4]; int priority; int runtime;

};

struct PCB pcb[5]; int q=5;

void main()

{ int p,i; strcpy(pcb[0].name,\序列队列,优先级由高到低为1,2,3..... pcb[0].priority = 2;

pcb[0].runtime = 3;

strcpy(pcb[1].name,\序列队列 pcb[1].priority = 3; pcb[1].runtime = 2;

strcpy(pcb[2].name,\序列队列 pcb[2].priority = 1;

pcb[2].runtime = 4;

strcpy(pcb[3].name,\序列队列 pcb[3].priority = 5;

pcb[3].runtime = 6;

strcpy(pcb[4].name,\序列队列 pcb[4].priority = 4; pcb[4].runtime = 5;

printf(\进程调度子菜单------------------------------\\n\

printf(\ 0---------退出系统\\n\

12

printf(\ 1---------优先级调度\\n\

printf(\ 2---------时间片调度\\n\ printf(\显示所有进程\\n\ for(i=0;i<5;i++) printf(\ %d %d\\n\ printf(\请选择您需要的功能选项:\ scanf(\

printf(\

while(1)

{

if(p==0) break; switch(p) {

//case 0:

//break; case 1: printf(\优先级调度算法\\n\ priority();

break;

case 2: printf(\时间片调度算法\\n\ time();

break;

}

printf(\请选择您需要的功能选项:\ scanf(\

printf(\

}

}

void priority() { int i,j;

int t=0,r=0;

//int q=5;

char name[2]=\ for(i=0;ipcb[j].priority)

{

13

strcpy(name,pcb[i].name); strcpy(pcb[i].name,pcb[j].name); strcpy(pcb[j].name,name); t=pcb[i].priority;

pcb[i].priority=pcb[j].priority;

pcb[j].priority=t;

r=pcb[i].runtime;

pcb[i].runtime=pcb[j].runtime; pcb[j].runtime=r;

} }

printf(\按优先级高低进行排序\\n\

for(i=0;i

printf(\ %d %d\\n\ printf(\ printf(\显示优先级最高的进程\\n\ printf(\ %d %d\\n\

for(i=0;i

strcpy(pcb[i].name,pcb[i+1].name); pcb[i].priority = pcb[i+1].priority; pcb[i].runtime = pcb[i+1].runtime; }

printf(\

printf(\使最高优先级进程处于执行状态(撤销该进程)\\n\ for(i=0;i

printf(\ %d %d\\n\

q=q-1;

}

void time() { int i,j,t; //int q=5; for(i=0;i

printf(\ %d %d\\n\ for(i=0;i

}

printf(\ printf(\将每个执行进程的执行时间减去一个时间片。\\n\

for(i=0;i

14

printf(\ %d %d\\n\

for(i=0;i

for(j=t;j

strcpy(pcb[j].name,pcb[j+1].name);

pcb[j].priority = pcb[j+1].priority;

pcb[j].runtime = pcb[j+1].runtime;

}

q=q-1; }

}

printf(\ printf(\将进行结束的进程撤销。\\n\ for(i=0;i

printf(\ %d %d\\n\ }

}

15

程序运行结果及分析

16

实验三:模拟动态分区首次适应分配和回收算法

实验目的:

通过本实验,可加深理解动态分区分配、回收程序的功能和具体实现,特别是对回收分区的合并的理解。

实验内容:

1、 设计动态分区首次适应分配、回收算法。 2、 设计“未分配区说明表”,格式为:

序号 1 始址 60k 长度 200 状态 1 0 3、设计“已分配区说明表”,格式为:

作业名 始址 长度 状态 0 0 4、 设计显示程序,将“未分配区说明表”和“已分配区说明表”的内容,显示在屏幕上。 初始分配从一个空闲区分配起,回收时要合并空区。

实验步骤:

1、 系统要求分配一个分区时,应输入:作业名、作业长度。

2、 回收一个分区时,应输入:回收的作业名。回收的分区请注意是否需要进行合并。

实验代码:

#include #include

int MAX_SEGMENT=10;//最大碎片值 struct Partition //分区表目

17

{ int Par_Size; //分区大小 int Par_No; //分区序号或者名字 int Addr; //分区地址

int IsUse; //分区使用情况,0表示空闲,1表示使用

Partition *pri; //前向指针

Partition *next;

//后向指针

};

Partition * Int()//函数,返回Partition类型指针 {

//初始化空闲分区表

Partition *list,*H,*H1;

list=(struct Partition *)malloc(sizeof(struct Partition));//malloc申请动态分配空间 list->next=NULL; H=list;

if(!list) { printf(\错误,内存初始化分配失败!程序结束\ exit(1);

}

H1=(struct Partition *)malloc(sizeof(struct Partition)); printf(\请预先输入分区总大小(以KB为单位):\ scanf(\

H1->Addr=0; H1->Par_No=0; H1->IsUse=0; H1->pri=H;

H1->next=NULL; H->next=H1;////list--->H1 return list;

}

Partition * InitFP() { //初始化已分配分区表 Partition *FP,*F,*H; int i;

FP=(struct Partition *)malloc(sizeof(struct Partition)); FP->next=NULL; H=FP;

for(i=0;i<10;i++) //已分配区先暂定分配十个表目

{ F=(struct Partition *)malloc(sizeof(struct Partition));

if(!F) { printf(\错误,内存分配失败!程序结束\

exit(1);

18

}

}

}

F->Par_Size=0; F->Addr=0; F->Par_No=0; F->IsUse=0; F->next=NULL; H->next=F; F->pri=H; H=H->next;

return FP;

Partition * New_Process( Partition *list, Partition *FP) { //为新的进程分配资源

Partition *H,*P,*H1; int Size,Name,L;

H=list;

H1=FP->next; H=H->next;

printf(\请输入新作业的名称和大小(整数)\\n\printf(\作业名称:\scanf(\

printf(\作业大小(整数):\scanf(\while(H) {

if(!H) {

//表目已查完,无法分配

printf(\已无空闲分区,本次无法分配!\return list;

} else{ if(H->IsUse==0) //if(H->Par_Size>=Size)

if(H->Par_Size>=Size) {

//空表目

//大小满足,空闲分区大小》要分配的大小 //大小满足,

bool temp=false; if((H->Par_Size-Size)<=MAX_SEGMENT){//空闲分区大小-要分配的大小<碎片值,会产生碎片,将整块内存大小分配出去,

Size=H->Par_Size;//分配的大小为整块内存 temp=true;//会产生碎片

}

//其他情况就分配大小为请求大小,不会产生碎片, L=H->Addr;//保存空闲分地址

19

去!\

if(temp){ printf(\该次内存分配会产生碎片,将整块内存大小%d分配出}else{ printf(\该次内存分配不会产生碎片\

} break;

} }

H=H->next;

//否则,继续往下查找

} if(H) {

if(H->Par_Size>Size) {

//大小满足,空闲分区大小》要分配的大小

//分配新的表目,

P=(struct Partition *)malloc(sizeof(struct Partition)); P->IsUse=1;

P->Addr=L;//指向空闲分区地址 P->next=H;

//修改指针

H->pri->next=P;

P->pri=H->pri; H->pri=P;

P->Par_Size=Size;//分配大小为要请求分配的大小 P->Par_No=Name;//名称

处理一条数据,分配一次内存

H->Par_Size-=Size; //修改空闲分区,H所指区块大小减Size H->Addr+=Size;//H所指区块地址加Size

}else { H->IsUse=1; }

while(H1) {

if(H1->IsUse==0) { }

H1=H1->next;

//大小相等的,把当前表项设置空表目

H1->Par_No=Name;

H1->Par_Size=Size;

H1->Addr=L;//保存已分配地址

H1->IsUse=1;//在已分配表中设置为已分配 break;

} }else

20

printf(\所申请资源已大过系统所拥有的,请重新输入!\\n\

return list; }

Partition *Reclaim( Partition *list, Partition *FP) { //结束作业,资源回收,No为作业名,回收内存

Partition * H1,*H2,*H3,*HF;//H1为释放区,H2为后分区,H3为前分区 int No; //作业名 H1=list;

HF=FP;//可有可无? H1=H1->next;

HF=FP->next;

printf(\请输入您想结束的作业名:\ scanf(\

while(HF)//对已分配表进行操作 { if(HF->Par_No==No) { HF->IsUse=0; //标志为空表目

break;//这时保存着HF所指分区的信息

}

HF=HF->next;

}

if(!HF) //如果找不到该作业,则提示出错 printf(\所输入的作业名称不正确,请重新输入!\ else{ while(H1)//对空闲表进行操作 { if(H1->Par_No==No) { H1->IsUse=0; //标志为空表目 printf(\内存回收成功\

break;

}

H1=H1->next;

}

H2=H1->next;//后分区 H3=H1->pri;//前分区

if(H2&&H2->IsUse==0) //后接分区为空闲 { if(H2->next==NULL) //判断后接分区是否为尾结点 { H1->Par_Size+=H2->Par_Size; //把H2合并到H1

H1->next=NULL;

free(H2);

21

printf(\已回收%d大小内存\

}else

//后分区不为空闲,表示已经被使用

{ H1->Par_Size+=H2->Par_Size; H1->next=H2->next; H2->next->pri=H1;

free(H2);

printf(\已回收%d大小内存\

}

}

if(H3&&H3->IsUse==0) //前分区为空闲分区,则合并去前分区 { H3->Par_Size+=H1->Par_Size; H3->next=H1->next; if(H1->next!=NULL) //若H1为尾结点

H1->next->pri=H3;

free(H1);

printf(\已回收%d大小内存\

}

}

return list;

}

void Print( Partition *list, Partition *FP) { //输出已分配分区和空闲分区 Partition *H1,*H2; H1=list->next; H2=FP;

H2=H2->next;

printf(\ printf(\总分配分区表*******************\\n\ printf(\分区序号 大小 开始地址 状态\\n\

while(H1) { printf(\

%d %d\

if(H1->IsUse==1) printf(\已分配\\n\ else printf(\空表目\\n\ H1=H1->next;

}

printf(\

}

void Main_Print( Partition *list, Partition *FP) { //主入口函数,进行菜单选择

22

int op;

while(1) { printf(\主菜单------------------------\\n\ printf(\

printf(\申请新的作业,分配内存\\n\ printf(\结束作业,回收内存\\n\ printf(\查看内存表\\n\ printf(\退出系统\\n\ printf(\请选择<1-4>:\ scanf(\ switch(op) //根据输入,选择分支方向

{

case 1: New_Process(list,FP);

break;

case 2: Reclaim(list,FP); break; case 3:

Print(list,FP);

break; case 4: break; default: printf(\选择错误,请重新选择!\

break; }

if(op==4) break;

//退出循环

}

}

void main()

{ //主函数入口

struct Partition *list,*FP; list=Int(); FP=InitFP(); Main_Print(list,FP);

}

23

程序运行结果及分析

24

实验五:模拟使用银行家算法判断系统的状态

实验目的:

了解进程管理的实现方法,理解和掌握处理进程同步问题的方法。

实验内容:

实现银行家算法、进程调度过程的模拟、读者-写者问题的写者优先算

法。

实验步骤:

?

理解安全性算法和银行家算法的核心机制:

? 理解进程的三状态调度过程,及各状态间的转换关系; ? 设计读者--写者问题的写者优先算法;

实验代码:

#include #include #include # define m 50

int no1; //进程数 int no2; //资源数

int r;

int allocation[m][m],need[m][m],available[m],max[m][m];

char name1[m],name2[m]; //定义全局变量 void main() {

void check(); void print(); int i,j,p=0,q=0; char c;

int request[m],allocation1[m][m],need1[m][m],available1[m]; printf(\银行家算法--------------------\\n\ printf(\请输入进程总数:\

scanf(\

25

printf(\请输入资源种类数:\

scanf(\

printf(\请输入最大需求矩阵:\\n\

for(i=0;i

for(j=0;j

for(i=0;i

printf(\请输入可利用资源矩阵\\n\

for(i=0;i

print(); //输出已知条件

check(); //检测T0时刻已知条件的安全状态 if(r==1) //如果安全则执行以下代码 {

do{ q=0;

p=0;

printf(\请输入请求资源的进程号(0~4):\\n\

for(j=0;j<=10;j++) {

scanf(\

if(i>=no1) { printf(\输入错误,请重新输入:\\n\ continue; }

else break; }

printf(\请输入该进程所请求的资源数request[j]:\\n\for(j=0;j

scanf(\for(j=0;jneed[i][j]) p=1;

26

//判断请求是否超过该进程所需要的资源数

if(p) printf(\请求资源超过该进程资源需求量,请求失败!\\n\ else { for(j=0;j

if(request[j]>available[j]) q=1; //判断请求是否超过可用资源数 if(q) printf(\没有做够的资源分配,请求失败!\\n\ else //请求满足条件 { for(j=0;j

allocation1[i][j]=allocation[i][j];

need1[i][j]=need[i][j];

//保存原已分配的资源数,仍需要的资源数和可用的资源数 available[j]=available[j]-request[j];

allocation[i][j]+=request[j];

need[i][j]=need[i][j]-request[j];

//系统尝试把资源分配给请求的进程 }

print();

check(); //检测分配后的安全性 if(r==0) //如果分配后系统不安全 { for(j=0;j

available[j]=available1[j];

allocation[i][j]=allocation1[i][j];

need[i][j]=need1[i][j];

//还原已分配的资源数,仍需要的资源数和可用的资源数 }

printf(\返回分配前资源数\\n\

print();

} }

}printf(\你还要继续分配吗?Y or N ?\\n\

//判断是否继续进行资源分配

c=getche(); }while(c=='y'||c=='Y');

}

27

}

void check() //安全算法函数 {

int k,f,v=0,i,j; int work[m],a[m]; bool finish[m]; r=1;

for(i=0;i

work[i]=available[i];//work[i]表示可提供进程继续运行的各类资源数 k=no1;

do{ for(i=0;i

{

if(finish[i]==false) {

f=1;

for(j=0;j

if(need[i][j]>work[j]) f=0;

if(f==1) //找到还没有完成且需求数小于可提供进程继续运行{ }

的资源数的进程

}

finish[i]=true;

a[v++]=i; //记录安全序列号

for(j=0;j

}

k--; //每完成一个进程分配,未完成的进程数就减1

}while(k>0); f=1;

for(i=0;i

if(finish[i]==false) { }

f=0; break;

28

if(f==0) //若有进程没完成,则为不安全状态 { printf(\系统处在不安全状态!\ r=0;

} else { printf(\系统当前为安全状态,安全序列为:\\n\ for(i=0;i

}

void print() //输出函数 { int i,j;

printf(\

printf(\此时刻资源分配情况*********************\\n\

printf(\进程名/号 | 最大需求矩阵 | 当前分配矩阵 | 需求矩阵 for (i = 0; i < no1; i++) { printf(\ p%d/%d \

for (j = 0; j < no2; j++)

{printf(\ \

for (j = 0; j < no2; j++)

{printf(\ %d \

for (j = 0; j < no2; j++)

{printf(\ \

printf(\

}

printf(\ printf(\各类资源可利用的资源数为:\ for (j = 0; j < no2; j++)

{printf(\

printf(\

}

|\\n\

29

程序运行结果及分析

30

31

本文来源:https://www.bwwdw.com/article/djg3.html

Top