河南省高等教育自学考试 实 验 报 告 册
计算机及应用专业(本科段)
《操作系统》
姓名 准考证号 所属地市 实验地点 实验日期 实验总成绩指导教师签名实验单位(实验室)意见: 主考院校审核意见:
河南科技大学自学考试办公室
2014 年 9 月 14 日
1
目 录
一、 实验报告要求…………………………………………………..1
二、 实验一:单处理器系统的进程调度模拟……………………..2
三、 实验二:可变分区管理方式的主存分配回收模拟…………...5
四、 实验三:文件操作模拟………………………………………...8
五、 实验四:银行家算法的模拟……………………………………10
2
实验报告要求
1、 实验报告应包括以下的内容:
(1)程序清单
(2)实验结果
(3)分析与讨论
2、实验报告应写明实验名称、班号、实验者姓名、学号、将实验报告整理装订好,按指导教师规定的时间上交。
基本实验方法
本实践环节要求学生能够顺利完成《数据库原理》、《数据结构》、《操作系统》、《面向对象程序设计》几门课程的实践操作 实验所用器件、设备的简单介绍
所有实验在586以上的微机上进行,运行环境为VFP、C语言、C++语言和Windows、Linux操作系统。
3
实验一:单处理器系统的进程调度模拟
一、 实验学时:2学时
二、 实验目的:通过模拟单处理器系统的进度调度,了解进程的构成、进程的组织及进程的状态及其转换,掌握进程调度策略。
三、 实验设备:本实验在586以上的微机上进行,运行环境为TurboC语言。
四、 样例:(参看《实践性环节培训与考核基本要求》P45)
五、 实验内容:
数据结构及说明:(模拟实验采用时间片轮调度)
Pcb-list是用于存放进程控制块的一个结构数组,每个元素都是一个Pcb结构。
Clock是自定义时钟 TIMESLTICE是时间片大小
NUMBER是系统允许并发执行的最大进程数
List/tail是进程就绪队列的头/尾指针
算法:
定义变量; 初始化就绪队列;
初始化PCB—LIST
CPU查询有多少进程输入,查到值赋给N;
对每个进程 输入到达进程的名称和运行时间
调用函数Pcb—malloc()给进程分配pcb块;
将进程加入就绪队列;
系统调度;(用schedule()实现)
4
if(运行完毕)
输出结束条件:
用用户控制结束。
(一)、实验目的
通过模拟单处理器系统的进度调度,了解进程的构成、进程的组织及进程的状态及其转换,掌握进程调度策略。
(二)、程序清单
#include "stdio.h"
#define running 1 /*用running 表示进程处于运行态*/
#define aready 2 /*用aready表示进程处于就绪态*/
#define blocking 3 /*用blocking表示进程处于等待态*/
#define sometime 5 /*用sometime 表示时间片大小*/
#define n 10 /* 假定系统允许进程个数为10 */
struct
{
int name; /*进程标识符*/
int status; /*进程状态*/
int ax, bx, cx,dx; /*进程现场信息,通用寄存器内容*/
int pc; /*进程现场信息,程序计数器内容*/
int psw; /*进程现场信息,程序状态字寄存器内容*/
int next; /*下一个进程控制块的位置*/
}pcbarea[n]; /*定义模拟进程控制块区域的数组*/
int PSW,AX,BX,CX,DX,PC,TIME; /*模拟寄存器*/
int run; /*定义指向正在运行进程的进程控制块的指针*/
struct
{
int head;
int tail;
}ready; /*定义指向就绪队列的头指针head和尾指针tail*/
int block; /*定义指向等待队列的指针*/
int pfree; /*定义指向空闲进程控制块队列的指针*/
sheduling( )
/*进程调度函数*/
{
int i;
if (ready.head==-1) /*空闲进程控制块队列为空,退出*/
{
5
printf("无就绪进程\n");
return 0;
}
i=ready.head; /*就绪队列头指针赋给i*/
ready.head=pcbarea[ready.head].next;/*就绪队列头指针后移*/
if(ready.head==-1)ready.tail=-1;/*就绪队列为空,修正尾指针ready.tail*/ pcbarea[i].status=running;/*修改进程控制块状态*/
TIME=sometime; /*设置相对时钟寄存器*/
/*恢复该进程现场信息:*/
AX=pcbarea[run].ax;
BX=pcbarea[run].bx;
CX=pcbarea[run].cx;
DX=pcbarea[run].dx;
PC=pcbarea[run].pc;
PSW=pcbarea[run].psw;
/*修改指向运行进程的指针*/
run=i;
return 0;
}/*进程调度函数结束*/
create( int x)
/*创建进程*/
{
int i;
if(pfree==-1) /*空闲进程控制块队列为空*/
{
printf("无空闲进程控制块,进程创建失败\n");
return 0;
}
i=pfree;/*取空闲进程控制块队列的第一个*/
pfree=pcbarea[pfree].next;/*pfree后移*/
/*填写该进程控制块内容:*/
pcbarea[i].name=x;
pcbarea[i].status=aready;
pcbarea[i].ax=x;
pcbarea[i].bx=x;
pcbarea[i].cx=x;
pcbarea[i].dx=x;
pcbarea[i].pc=x;
pcbarea[i].psw=x;
if(ready.head!=-1)
{
/*就绪队列不空时,挂入就绪队列方式*/
pcbarea[ready.tail].next=i;
ready.tail=i;
6
pcbarea[ready.tail].next=-1;
}
else
{
/*就绪队列空时,挂入就绪队列方式:*/
ready.head=i;
ready.tail=i;
pcbarea[ready.tail].next=-1;
}
} /*进程创建函数结束*/
main( )
{
/*系统初始化*/
int num,j;
run=ready.head=ready.tail=block=-1;
pfree=0;
for(j=0;j<n-1;j++)
pcbarea[j].next=j+1;
pcbarea[n-1].next=-1;
printf("输入进程编号(避免编号的冲突,以负数输入结束,最多可以创建10个进程):\n");
scanf("%d",&num);
while(num>0)
{
create(num);
scanf("%d",&num);
}
sheduling( );
if(run!=-1)
{
printf("进程名 进程状态 寄存器内容:ax bx cx dx pc psw:\n");
printf("%4d%10d %14d%3d%3d%3d%3d%3d\n",pcbarea[run].name,
pcbarea[run].status,pcbarea[run].ax, pcbarea[run].bx, pcbarea[run].cx, pcbarea[run].dx, pcbarea[run].pc, pcbarea[run].psw);
}
return 0;
}/*main( )结束*/
(三)、实验中出现的问题及解决的方法
这个实验模拟单处理器系统的进度调度,了解进程的构成、进程的组
织及进程的状态及其转换,掌握进程调度策略。
7
8
实验二:可变分区管理方式的主存分配回收模拟
一、 实验学时:2学时
二、 实验目的:通过模拟可变分区管理方式下主存的分配和回收,主要了解内存的管理思想,以及掌握分区的几种策略。
三、 实验设备:本实验在586以上的微机上进行,运行环境为TurboC语言。
四、 样例:(参看《实践性环节培训与考核基本要求》P54)
五、 实验内容:
数据结构及说明:(模拟试验采用首次适应策略)
空闲区链表FBC,分配区链表ABC;
表中纪录块的起始地址和大小,块按照地址大小从小到大排列。 功能实现
分配时:根据作业的大小,从第一个空闲块查找,将找到的第一个足够大的空闲块分配给该作业,返回给用户该块始地址。
回收时:根据用户提供的作业的始地址,在分配区表中查找,若找到,加入空闲区链表,提示用户释放成功。
显示:用户可随时选择查看内存分配状态图。
主要子函数
Void show-block void display-men(void) void display(void) void add-abcNode void assign() void add-fbcNode
9
void release(void)
(一)、实验目的
通过模拟可变分区管理方式下主存的分配和回收,主要了解内存的管理思想,以及掌握分区的几种策略。
(二)、程序清单
//动态分区存储管理方式的主存分配回收
#include<fstream.h>
#include<iostream.h>
#include<iomanip.h>
#include<string.h>
#include<process.h>
#define n 10 //假定系统允许的最大作业为,假定模拟实验中n值为10
#define m 10 //假定系统允许的空闲区表最大为m,假定模拟实验中m值为10 #define minisize 100
ofstream out("output.txt");
typedef struct
{
float address; //已分分区起始地址
float length; //已分分区长度,单位为字节
int flag; //已分配区表登记栏标志,用"0"表示空栏目,实验中只支持一个字符的作业名 }used; //已分配区表
used used_table[n];
typedef struct
{
float address; //空闲区起始地址
float length; //空闲区长度,单位为字节
int flag; //空闲区表登记栏标志,用"0"表示空栏目,用"1"表示未分配
}freed; //空闲区表
freed free_table[m];
//采用最优分配算法分配xk大小的空间
void allocate(char J,float xk)
{
int i,k;
float ad;
k=-1;
for(i=0;i<m;i++) //寻找空间大于xk的最小空闲区登记项k
if(free_table[i].length>=xk&&free_table[i].flag==1)
if(k==-1||free_table[i].length<free_table[k].length)
k=i;
if(k==-1)//未找到可用空闲区,返回
{
10
cout<<"无可用空闲区"<<endl;
return;
}
//找到可用空闲区,开始分配:若空闲区大小与要求分配的空间差小于msize大小,则空闲区全部分配;若空闲区大小与要求分配的空间差大于minisize大小,则从空闲区划出一部分分配
if(free_table[k].length-xk<=minisize)
{
free_table[k].flag=0;
ad=free_table[k].address;
xk=free_table[k].length;
}
else
{
free_table[k].length=free_table[k].length-xk;
ad=free_table[k].address+free_table[k].length;
}
//修改已分配区表
i=0;
//寻找空表目
while(used_table[i].flag!=0&&i<n) i++;
//无表目填写已分分区
if(i>=n)
{
cout<<"已分配区表长度不足,分配失败,出错"<<endl;
//修正空闲区表
if(free_table[k].flag==0)
free_table[k].flag=1;
//前面找到的是某个空闲分区的一部分
else
{
free_table[k].length=free_table[k].length+xk;
return;
}
}
//修改已分配表
else
{
used_table[i].address=ad;
used_table[i].length=xk;
used_table[i].flag=J;
}
return;
}
11
//回收作业名为J的作业所占主存空间
void reclaim(char J)
{
int i,k,j,s,t;
float S,L;
//寻找已分配表中对应登记项
s=0;
while((used_table[s].flag!=J||used_table[s].flag==0)&&s<n)
s++;
//在已分配表中找不到名字为J的作业
if(s>=n)
{
cout<<"未找到作业,回收失败"<<endl;
return;
}
//修改已分配表
used_table[s].flag=0;
//取得归还分区的起始地址S和长度L
S=used_table[s].address;
L=used_table[s].length;
j=-1;
k=-1;
//寻找回收分区的空闲上下邻,上邻表目k,下邻表目j
i=0;
while(i<m&&(j==-1||k==-1))
{
if(free_table[i].flag==1)
{
if(free_table[i].address+free_table[i].length==S) k=i;//找到上邻 if(free_table[i].address==S+L) j=i;//找到下邻
}
i++;
}
if(k!=-1)
if(j!=-1) //上邻空闲区,下邻空闲区,三项合并
{
free_table[k].length=free_table[j].length+free_table[k].length+L; free_table[j].flag=0;
}
else //上邻空闲区,下邻非空闲区,与上邻合并
free_table[k].length=free_table[k].length+L;
else
if(j!=-1) //上邻非空闲区,下邻为空闲区,与下邻合并
{
12
free_table[j].address=S;
free_table[j].length=free_table[j].length+L; }
else //上下邻均为非空闲区,回收区域直接填入 { //在空闲区表中寻找空栏目
t=0;
while(free_table[t].flag==1&&t<m)
t++;
if(t>=m)//空闲区表满,回收空间失败,将已分配表复原 {
cout<<"主存空闲表没有空间,回收空间失败"<<endl; used_table[s].flag=J;
return;
}
free_table[t].address=S;
free_table[t].length=L;
free_table[t].flag=1;
}
return;
}
//主函数
void main( )
{
int i,j;
float xk;
char s;
ifstream in("input.txt");
//空闲分区表初始化
free_table[0].address=10240;
free_table[0].length=102400;
free_table[0].flag=1;
for(i=1;i<m;i++)
free_table[i].flag=0;
//已分配表初始化
for(i=0;i<n;i++)
used_table[i].flag=0;
while(1)
{
cout<<" 请输入演示功能项: "<<endl;
cout<<"================================="<<endl<<endl; cout<<" 0.退出 "<<endl<<endl; cout<<" 1.分配主存 "<<endl<<endl; cout<<" 2.回收主存 "<<endl<<endl; 13
cout<<" 3.显示主存 "<<endl<<endl;
cout<<"================================="<<endl<<endl;
cout<<" 请输入(0-3):"<<endl;
cin>>j;
cout<<j<<endl;
cout<<endl;
switch(j)
{
case 0:
exit(0);
case 1:
cout<<"输入作业名s(注意:只能是一个字符): "<<endl;
cin>>s;
cout<<s<<endl;
cout<<"作业所需长度xk: "<<endl;
cin>>xk;
cout<<xk<<endl;
allocate(s,xk);
break;
case 2:
cout<<"输入要回收分区的作业名(注意:只能是一个字符)"<<endl;
cin>>s;
cout<<s<<endl;
reclaim(s);
break;
case 3:
cout<<"输出空闲区表:\n起始地址 分区长度 标志\n";
for(i=0;i<m;i++)
cout<<setw(6)<<free_table[i].address<<setw(9)<<free_table[i].length<<setw(6)<<free_table[i].flag<<endl;
cout<<" 输出已分配区表:\n起始地址 分区长度 标志\n";
for(i=0;i<n;i++)
if(used_table[i].flag!=0)
cout<<setw(6)<<used_table[i].address<<setw(9)<<used_table[i].length<<setw(6)<<char(used_table[i].flag)<<endl;
else
cout<<setw(6)<<used_table[i].address<<setw(9)<<used_table[i].length<<setw(6)<<used_table[i].flag<<endl;
break;
default:
cout<<"没有该选项"<<endl;
14
}//case
}//while
}//主函数结束
(三)、实验中出现的问题及解决的方法
这个实验通过模拟可变分区管理方式下主存的分配和回收,了解内存的管理思想,并且掌握分区的几种策略。
15
实验三:文件操作模拟
一、 实验学时:2学时
二、 实验目的:通过编程练习文件系统提供的文件操作,了解和掌握文件管理系统工作原理。主要了解文件的物理结构、目录管理、外存空间的管理以及文件的保护和保密。
三、 实验设备:本实验在586以上的微机上进行,运行环境为TurboC语言。
四、 样例:(参看《实践性环节培训与考核基本要求》P96)
五、 实验内容:
实现文件的建立和读写操作。首先建立文件File1和File2,然后从键盘输入,并将输入的内容写入File1中,然后将File1中的内容以倒序写入File2中,最后将File2的内容显示。
(一)、实验目的
过编程练习文件系统提供的文件操作,了解和掌握文件管理系统工作原理。主要了解文件的物理结构、目录管理、外存空间的管理以及文件的保护和保密。
(二)、程序清单
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
16
public class Test
{
public static void main(String[] args) throws IOException { } File file1 = new File("D:/f1.txt"); File file2 = new File("D:/f2.txt"); int c; InputStream input1 = System.in; InputStreamReader reader1 = new InputStreamReader(input1); FileWriter writer1 = new FileWriter(file1); while ((c = reader1.read()) != -1) { } writer1.close(); FileReader reader2 = new FileReader(file1); FileWriter writer2 = new FileWriter(file2); ArrayList<Integer> list = new ArrayList<Integer>(); while ((c = reader2.read()) != -1) { } for (int i = list.size() - 1; i >= 0; --i) { } writer2.close(); writer2.write(list.get(i)); list.add(c); writer1.write(c);
(三)、实验中出现的问题及解决的方法
通过这个实验让我更加了解了操作系统中的原理和使用方式。
17
实验四 银行家算法的模拟
一、实验学时:2学时
二、实验目的:通过对银行家算法的模拟,了解死锁的概念、死锁的本质以及掌握解决死锁的方法。
三、 实验设备:本实验在586以上的微机上进行,运行环境为TurboC语言。
四、 样例:(参看《实践性环节培训与考核基本要求》P101)
五、 实验内容:
数据结构定义:
可用资源向量 available
分配矩阵 allocation
剩余需求矩阵 need
系统拥有资源向量 max-resource
安全状态标志向量 finish
程序要求
对每一种资源进行安全检验,要求该程序在静态的条件下输入系统的状态,和每个进程拥有资源的状态,来判断系统是否安全。
(一)、实验目的
通过对银行家算法的模拟,了解死锁的概念、死锁的本质以及掌握解决死锁的方法。
(二)、程序清单
#include <iostream.h>
18
//全局变量定义
int Available[100]; //可利用资源数组
int Max[50][100]; //最大需求矩阵
int Allocation[50][100]; //分配矩阵
int Need[50][100]; //需求矩阵
int Request[50][100]; //M个进程还需要N类资源的资源量 int Finish[50];
int p[50];
int m,n; //M个进程,N类资源
//安全性算法
int Safe()
{
int i,j,l=0;
int Work[100]; //可利用资源数组
for (i=0;i<n;i++)
Work[i]=Available[i];
for (i=0;i<m;i++)
Finish[i]=0;
for (i=0;i<m;i++)
{
if (Finish[i]==1)
continue;
else
{
for (j=0;j<n;j++)
{
if (Need[i][j]>Work[j])
break;
}
if (j==n)
{
Finish[i]=1;
for(int k=0;k<n;k++)
Work[k]+=Allocation[i][k];
p[l++]=i;
i=-1;
}
else continue;
}
if (l==m)
{
cout<<"系统是安全的"<<'\n';
cout<<"系统安全序列是:\n";
19
for (i=0;i<l;i++)
{
cout<<p[i];
if (i!=l-1)
cout<<"-->";
}
cout<<'\n';
return 1;
}
}
}
//银行家算法
int main()
{
int i,j,mi;
cout<<"输入进程的数目:\n";
cin>>m;
cout<<"输入资源的种类:\n";
cin>>n;
cout<<"输入每个进程最多所需的各类资源数,按照"<<m<<"x"<<n<<"矩阵输入\n"; for (i=0;i<m;i++)
for(j=0;j<n;j++)
cin>>Max[i][j];
cout<<"输入每个进程已经分配的各类资源数,按照"<<m<<"x"<<n<<"矩阵输入\n"; for (i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
cin>>Allocation[i][j];
Need[i][j]=Max[i][j]-Allocation[i][j];
if (Need[i][j]<0)
{
cout<<"你输入的第"<<i+1<<"个进程所拥有的第"<<j+1<<"个资源错误,请重新输入:\n";
j--;
continue;
}
}
}
cout<<"请输入各个资源现有的数目:\n";
for (i=0;i<n;i++)
cin>>Available[i];
Safe();
20
while (1)
{
cout<<"输入要申请的资源的进程号:(第一个进程号为0,第二个进程号为1,依此类推)\n";
cin>>mi;
cout<<"输入进程所请求的各个资源的数量\n";
for (i=0;i<n;i++)
cin>>Request[mi][i];
for (i=0;i<n;i++)
{
if (Request[mi][i]>Need[mi][i])
{
cout<<"所请求资源数超过进程的需求量!\n";
return 0;
}
if (Request[mi][i]>Available[i])
{
cout<<"所请求资源数超过系统所有的资源数!\n";
return 0;
}
}
for (i=0;i<n;i++)
{
Available[i]-=Request[mi][i];
Allocation[mi][i]+=Request[mi][i];
Need[mi][i]-=Request[mi][i];
}
if (Safe())
cout<<"同意分配请求~~~\n";
else
{
cout<<"SORRY╮(╯▽╰)╭……你的请求被拒绝…\n";
for (i=0;i<n;i++)
{
Available[i]+=Request[mi][i];
Allocation[mi][i]-=Request[mi][i];
Need[mi][i]+=Request[mi][i];
}
}
for (i=0;i<m;i++)
Finish[i]=0;
char Flag; //标志位
cout<<"是否再次请求分配?是请按Y/y,否请按N/n";
while (1)
21
}
} { cin>>Flag; if (Flag=='Y'||Flag=='y'||Flag=='N'||Flag=='n') break; else { cout<<"请按要求重新输入:\n"; continue; } } if (Flag=='Y'||Flag=='y') continue; else break;
(三)、实验中出现的问题及解决的方法
没有什么问题但是银行家算法,有效的防止和避免死锁的发生,值得好好学习。
22
《计算机操作系统》实验报告班级:姓名:学号:实验一进程控制与描述一、实验目的通过对Windows2000编程,进一步熟悉操作系统的…
操作系统实验报告实验名称理解UNIXLINUXShell及UNIX的进程树成绩专业班级计科姓名学号联系电话实验日期20xx年12月…
目录实验一进程的创建2实验二进程控制3实验三进程的管道通信4实验四消息通信6实验五进程调度算法8实验六FIFO页面置换算法12实验…
操作系统实验报告学号姓名班级实验一实验报告实验名称并发程序设计实验1实验目的掌握在程序中创建新进程的方法观察并理解多道程序并发执行…
《操作系统原理》实验报告院(部):管理工程学院专业:信息管理与信息系统实验项目:实验一二三五班级:信管102姓名:学号:目录引言.…
操作系统实验题设计一若干并发进程的进程调度程序一实验目的无论是批处理系统分时系统还是实时系统用户进程数一般都大于处理机数这将导致用…
1实验目的通过优先权法和轮转算法的模拟加深对进程概念和进程调度过程的理解掌握进程状态之间的切换同时掌握进程调度算法的实现方法和技巧…
1实验目的通过优先权法和轮转算法的模拟加深对进程概念和进程调度过程的理解掌握进程状态之间的切换同时掌握进程调度算法的实现方法和技巧…
操作系统进程调度实验报告一实验目的用高级语言编写和调试一个进程调度程序以加深对进程的概念及进程调度算法的解进程调度时进程管理的主要…
实验一进程调度实验专业XXXXX学号XXXXX姓名XXX实验日期20XX年XX月XX日一实验目的通过对进程调度算法的模拟加深对进程…