计算机基于Linux的操作系统实验指导书docx.docx
《计算机基于Linux的操作系统实验指导书docx.docx》由会员分享,可在线阅读,更多相关《计算机基于Linux的操作系统实验指导书docx.docx(44页珍藏版)》请在冰点文库上搜索。
![计算机基于Linux的操作系统实验指导书docx.docx](https://file1.bingdoc.com/fileroot1/2023-5/2/bac74cc6-3ba1-44ed-a292-97d7308170e4/bac74cc6-3ba1-44ed-a292-97d7308170e41.gif)
计算机基于Linux的操作系统实验指导书docx
计算机操作系统课程实验
实验授课计划
序
号
实验项目
学时
要
求
实验类型
实验要求
实验
时间
1
认识Linux系统;Vi编辑器、编译工具gcc的使用
2
必
修
验
证
上机
练习
1-2周
2
进程控制
2
必
修
验
证
运行命令、例
程
并分析结果
3-4周
3
银行家算法的模拟实现
4
必
修
综
合
编程
并运行通过
5-8周
4
Linux内存管理
2
必
修
验
证
运行命令、例
程
并分析结果
9-10周
5
页面置换算法的模拟实现(存储管理)
2
必
修
综
合
编程
并运行通过
11-12周
6
Linux设备管理、
Linux文件管理
4
选
修
验
证
运行命令、例
程
并分析结果
13-14周
实验一:
认识Linux系统
【实验目的】
了解Linux的启动过程;了解Linux文件的组织结构;熟悉XWindow环境;熟练掌握Linux常用命令。
【准备知识】
登录Linux是一个多用户多任务操作系统,多个用户可以拥有自己独立的用户账号
登录提示:
RedHatLinuxrelease6.0(Hedwing)
Kernel2.2.5-15onani686
Login:
此时输入用户户名(账号)并键入回车,则系统显示“passward”。
在输入密码和回车。
登录后:
[root@hawk/root]#
#表示是按root方式登录,$表示是普通用户。
Linux大小写敏感,用加参数
zlinux:
~#Is-F
HowTo/HowToMin/linux@nag/sag/
获取帮助:
Linux带有联机手册,可以用man命令来阅读
Zlinux:
〜$manIs
虚拟终端Linux可有多个用户登录到同一个计算机,但一般微机只有一个终端难以体现。
可以使用多个虚拟终端,用Alt+Fl、Alt+F2等来切换。
退出系统在停止使用系统时,要退出系统。
具体方法:
exit或logout,或Ctrl+D
关机如果没有用户在使用系统,可以关机。
但是不能直接关闭电源,而要按正常顺序关机。
一般用户是不能关机的,只有root用户可以关机。
方法:
可以使用halt或shutdown命令,也可以同时键入Ctrl+Alt+Del。
Windows虚拟机环境:
登录到系统
点击桌面“VMware"图标>VmwareWorkstation窗口>Commands>Startthis
virtualmachine
进入fedora后,用户名:
root
口令:
123456
【实验内容】
(1)熟悉开机、登录、退出、关机步骤。
(2)查看并记录所在机器Linux操作系统目录结构,特别是源代码所在的目录及文件。
(3)常用命令练习
1.注销(退出)系统:
logout或exit
2.练习使用命令Is(注意Linux命令区分大小写。
)
使用Is查看当前目录内容;使用Is查看指定目录内容,如/目录,/etc目录
使用Is-all查看当前目录内容;使用dir查看当前目录内容
3.使用cd改变当前目录
cd..回到上层目录;cd/回到根目录
4.pwd显示当前路径
5・建立目录mkdir
mkdir目录名;mkdir/home/s2001/newdir
6.删除目录:
rmdir;
7.复制文件cp:
如cp文件名1文件名2
8.移动文件或目录:
mv
9.删除文件rm
10.显示文件内容:
more(分页显示);
11.显示文件:
cat文件名建立文件:
cat>文件名,ctrl+d结束输入
(4)启动XWINDOW,熟悉窗口界面环境。
实验二:
Vi编辑器、编译工具gcc的使用
【实验目的】
熟练使用Linux的Vi编辑器;掌握Linux编译工具gcc的使用方法。
【准备知识】
设计程序需要一个环境一编辑和编译器oLinux的Vi为一个编辑器,gcc是C的编译器。
由他们实现源文件的的编辑和目标文件的编译执行。
【实验内容】
1.练习使用Linux编辑器Vi,为今后输入源程序做准备。
2.学习并掌握Linux编译工具gcc的使用方法
【实验指导】
使用编辑器vi编辑文件
1.进入linux的文本模式之后,在命令行键入vifilenames然后回车。
下面作一些简单的解释:
首先vi命令是打开vi编辑器。
后面的filenames是用户即将编辑的c文件名字,注意扩展名字是.c;当然,vi编辑器功能很强,可以用它来编辑其它格式的文件,比如汇编文件,其扩展名字是.s;也可以直接用vi打开一个新的未命名的文件,当保存的时候再给它命名,只是这样做不很方便。
2.最基本的命令I:
当进入刚打开的文件时,不能写入信息,这时按一下键盘上的I键
(insert),插入的意思,就可以进入编辑模式了。
如下图所示:
nain(){
2,26-33全部
3.a与i是相同的用法
4,当文件编辑完后,需要保存退出,这时需要经过以下几个步骤:
1)按一下键盘上的
Esc键;2)键入冒号(:
),紧跟在冒号后面是wq(意思是保存并退出)。
如果不想保存退出,则在第二步键入冒号之后,键入!
q(不带w,机尾部保存)。
如下图所示:
nsin(){
println(*tfc*IIouorId!
*):
}
5.退出vi编辑器的编辑模式之后,要对刚才编写的程序进行编译。
编译的命令是:
gccfilenames[-ooutputfilename],其中gcc是c的编译器。
参数:
filenames是刚才编辑的c文件(当然也可以是以前编写好的c文件);后面中括号里面的参数是可选的,它是一个输出文件。
如果不选,默认的输出文件是a.out,选了之后输出文件就是outputfilename,out.
6.最后一步是运行程序,方法如下:
./outputfilename.out
实验三:
进程控制
【实验目的】
(1)加深对进程概念的理解,明确进程和程序的区别。
(2)进一步认识并发执行的实质。
(3)分析进程竞争资源现象,学习解决进程互斥的方法。
【准备知识】
(1)阅读Linux的sched.h源文件,加深对进程管理概念的理解。
(2)阅读Linux的fork,c源文件,分析进程的创建过程。
(3)fork()函数:
创建一个新进程
intfork()
其中返回int取值意义如下:
0:
创建子进程,从子进程返回的id值
大于0:
从父进程返回的子进程id值
【实验内容】
(1)进程的创建
编写一段源程序,使系统调用fork。
创建两个子进程,当此程序运行时,在系统中有一个父进程和两个子进程活动。
让每一个进程在屏幕上显示一个字符:
父进程显示字符“a”;子进程分别显示字符“b”和字符“c”。
试观察纪录屏幕上的显示结果,并分析原因。
(2)进程的控制
修改已编写的程序,将每个进程输出一个字符改为每个进程输出一句话,在观察程序执行时屏幕出现的现象,并分析原因。
【思考】
(1)系统是怎样创建进程的?
(2)可执行文件加载时进行了哪些处理?
(3)当首次调用新创建进程时,其入口在哪里?
【实验指导】
1.进程的创建
〈任务〉
编写一段程序,使用系统调用fork()创建两个子进程。
当此程序运行时,在系统中有一个父进程和两个子进程活动。
让每一个进程在屏幕上显示一个字符;父进程显示字符“a”,子进程分别显示字符“b”和“c”o试观察记录屏幕上的显示结果,并分析原因。
〈程序〉
#include
main()
{
intpl=0,p2=0;
/*了进程创建成功*/
/*子进程创建成功*/
/*父进程执行*/
if(pl=fork())
putchar(b);
else
{
if(p2=fork())
putchar('c');
elseputchar('a');
}
}
〈运行结果〉
bca(有时会出现bac)
分析:
从进程执行并发来看,输出bac,acb等情况都有可能。
原因:
fork()创建进程所需的时间多于输出一个字符的时间,因此在主进程创建进程2的同时,进程1就输出了“b”,而进程2和主程序的输出次序是有随机性的,所以会出现上述结果。
2.进程的控制
〈任务〉
修改已编写好的程序,将每个程序的输出由单个字符改为一句话,再观察程序执行时屏幕上出现的现象,并分析其原因。
如果在程序中使用系统调用lockf()来给每个程序加锁,可以实现进程之间的互斥,观察并分析出现的现象。
〈程序〉
#include
main()
{
intpl,p2,i;
if(pl=fork())
for(i=0;i<500;i++)
printf(nchild%d\n”,i);
else
{
if(p2=fork())
for(i=0;i<500;i++)
printf("son%d\n",i);
else
for(i=0;i<500;i++)
printf("daughter%d\n",i);
〈运行结果〉
child・・・.
son…
daughter***
daughter***
或child
••,son
,,child
••son
•,daughter
分析:
由于函数printf()输出的字符串之间不会被中断,因此,字符串内部的字符顺序输出时不变。
但是,由于进程并发执行时的调度顺序和父子进程的抢占处理机问题,输出字符串的顺序和先后随着执行的不同而发生变化。
这与打印单字符的结果相同。
实验四:
银行家算法的模拟实现
【实验目的】
(1)进一步理解利用银行家算法避免死锁的问题;
(2)在了解和掌握银行家算法的基础上,编制银行家算法通用程序,将调试结果显示在计算机屏幕上,再检测和笔算的一致性。
(3)理解和掌握安全序列、安全性算法。
【实验内容】
(1)正确设置相应的数据结构;
(2)清晰画出算法流程图;
(3)准确实现教材第97-98页例题。
【实验原理】
一、安全状态
指系统能按照某种顺序如(称为〈Pl,P2,Pn>序列为安全序列),为每个
进程分配所需的资源,直至最大需求,使得每个进程都能顺利完成。
二、银行家算法
假设在进程并发执行时进程i提出请求j类资源k个后,表不为Requestsj]=k。
系统按下述步骤进行安全检查:
(1)如果RequestiWNeedi则继续以下检查,否则显示需求申请超出最大需求值的错误。
(2)如果RequestAvailable则继续以下检查,否则显示系统无足够资源,Pi阻塞等待。
(3)系统试探着把资源分配给进程Pi,并修改下面数据结构中的数值:
Available[j]:
^Available[j]-Requesti[j];
Allocation[i,j]:
^Allocation[i,j]+Requesti[j];
Need[i,j]:
=Need[i,j]-Requesti[j];
(4)系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态。
若安全,才正式将资源分配给进程Pi,以完成本次分配;否则,将本次的试探分配作废,恢复原来的资源分配状态,让进程Pi等待。
三、安全性算法
(1)设置两个向量:
1工作向量Work:
它表示系统可提供给进程继续运行所需的各类资源数目,它含有0个元素,在执行安全算法开始时,Work:
^Available:
2Finish:
它表示系统是否有足够的资源分配给进程,使之运行完成。
开始时先做Finish[i]:
=false;当有足够资源分配给进程时,再令Finish[i]:
=true。
(2)从进程集合中找到一个能满足下述条件的进程:
1Finish[i]=false;
2Need[i,j]WWork[j];若找到,执行步骤(3),否则,执行步骤(4)。
(3)当进程Pi获得资源后,可顺利执行,直至完成,并释放出分配给它的资源,故应执行:
>Work[j]:
=Work[i]+A1location[i,j];
>Finish[i]:
=true:
>gotostep2;
(4)如果所有进程的Finish[i]=true都满足,则表示系统处于安全状态;否则,系统处于不安全状态。
【实验寸旨导】参考实验步骤如下:
(1)参考图1-1所示流程图编写安全性算法。
图1-1安全性算法流程图
(2)编写统一的输出格式。
每次提出申请之后输出申请成功与否的结果。
如果成功还需要输出变化前后的各种数据,并且输出安全序列。
(3)参考图1-2所示流程图编写银行家算法。
(4)编写主函数来循环调用银行家算法。
【思考题】
(1)在编程中遇到了哪些问题?
你是如何解决的?
(2)在安全性算法中,为什么不用变量Available,而乂定义一个临时变量work?
结束
图1-2银行家算法流程图
实验五:
Linux内存管理
【实验目的】
理解需要动态存储分配的原因;掌握如何进行动态分配。
【准备知识】
分配内存空间所使用的函数调用如下
#include
void*malloc(size_tsize);
函数用于分配动态内存空间,size表示申请分配的内存空间的大小,以字节记。
释放原先配置的函数
#include
voidfree(void*ptr);
参数ptr为指向先前由malloc0函数所返回的内存指针。
调用free后ptr所指的内存空间会被收回。
假如参数ptr所指的内存空间已被收回获是未知的内存地址,则调用free可能有无法预料的情况发生。
若参数ptr为NULL则free。
不会有作用。
Read。
函数:
#include
Ssize_tread(intfd,void*buf,size_tcount);
Read()会把参数fd所指的文件传送count个字节到buf指针所指的内存中。
若参数count为0,则read。
不会有作用并返回0。
返回值为实际读到的字节数,如果返回0,表示已到达文件尾或是无可读取的数据,此外文件读写位置会随读取到的字节移动。
fstat()函数:
#include
#include
intfstat(intfiledes,structstat*buf);
函数用来将参数filedes所指的文件状态,复制到参数buf所指的结构中
(structstat)o执行成功则返回0,失败返回T。
【实验内容】
(1)编写程序完成以下功能:
a.申请一块内存空间
b.复制字符串"hello”到分配的内存
c.打印出该字符串及内存地址
d.释放申请的内存空间
(2)编写程序完成以下功能:
在打开文件后,通过fstat()获得文件长度,然后通过malloc()系统调用申请响应大小的内存空间,通过read。
将文件内容完全读入该内存空间,并显示出来。
【实验指导】
用malloc申请空间:
#include
#include
#include
#include
intmain(void)
(
char*str;
if((str=malloc(10))==NULL)
(
printf("Notenoughmemorytoallocatebuffer\n");
exit
(1);/*terminateprogramifoutofmemory*/
)
/*copy"Hello"intostring*/
strcpy(str,"Hello");
/*displaystring7
printf("Stringis%s\n",str);
/*freememory*/
free(str);
return0;
}
显示/etc/passwd文件大小读指定长度空间:
#include
#include
#include
main()
(
structstatbuf;
char*str;
intfd,fsize;
fd=open(<7etc/passwd,,,0_RDONLY)
fsize=fstat(fd,&buf);
printf("/etc/passwdfilesize=%d\n”,buf.st_size);
if((str=malloc(fsize))==NULL)
(
printf("Notenoughmemorytoallocatebuffer\n");
exit
(1);/*terminateprogramifoutofmemory*/
)
if((bytes=read(fd,str,fsize))==-1)(
printf("ReadFailedAn");
exit
(1);
)
else(
printf("Read:
%dbytesreadAn",bytes);
return0;
实验六:
页面置换算法的模拟实现(存储管理)
【实验目的】
存储管理的主要功能之一是合理地分配空间o请求页式管理是一种常用的虚拟存储管理技术。
本实验的目的是通过请求页式存储管理中页面置换算法模拟设计,了解虚拟存储技术的技术特点,掌握请求页式存储管理的页面置换算法。
【实验内容】
(1)通过随机数产生一个指令序列,共320条指令。
指令的地址按下述原则生成:
150%的指令是顺序执行的;
250%的指令是均匀分布在前地址部分;
350%的指令是均匀分布在后地址部分。
具体的实施方法是:
1在[0,319]的指令之间随即选取一起点m;
2顺序执行一条指令,即执行地址为m+1的指令;
3在前地址[0,m+1]中随机选取一条指令并执行,该指令的地址为;
4顺序执行一条指令,其地址为mz+1;
5在后地址[m‘+2,319]中随机选取一条指令并执行;
6重复上述步骤①-⑤,直到执行320次指令。
(2)将指令序列变换为页地址流
设:
①页面大小为旅;
2用户内存容量为4页到32页;
3用户虚存容量为32k„
在用户虚存中,按每k存放10条指令排在虚存地址,即320条指令在虚存中的存放方式为:
第0条-第9条指令为第0页(对应虚存地址为[0,9]);
第10条-第19条指令为第一页(对应虚存地址为[10,19]);
第310条~第319条指令为第31页(对应虚地址为[310,319])。
按以上方式,用户指令可组成32页。
(3)计算并输出下述各种算法在不同内存容量下的命中率。
1先进先出的算法(FIFO);
2最近最少使用算法(LRR);
3最佳淘汰算法(OPT)先淘汰最不常用的页地址;
4最少访问页面算法(LFR);
5最近最不经常使用算法(NUR)o
其中③和④为选择内容。
命中率=1—页面失效次数/页地址流长度
在本实验中,页地址流长度为320,页面失效次数为每次访问相应指令时,该指令所对
应的页不在内存的次数。
3、随机数产生办法,Linux或UNIX系统提供函数strand()和rand。
,分别进行初始化和产生随机数。
例如:
strand();
语句可初始化一个随机数;
a[0]=10*rand()/65535*319+1;
a[l]=10*rand()/65535*a[0]:
语句可用来产生a[0]与a[l]中的随机数。
【实验指导】
〈任务〉
设计一个虚拟存储区和内存工作区,并使用下列算法计算访问命中率.
(1)进先出的算法(FIFO)
(2)最近最少使用的算法(LRU)
(3)最佳淘汰算法(OPT)
(4)最少访问页面算法(LFU)
(5)最近最不经常使用算法(NUR)
命中率=(1一页面失效次数)/页地址流长度
〈程序设计〉
本实验的程序设计基本上按照实验内容进行。
即首先用srandO和randO函数定义和产生指令序列,然后将指令序列变换成相应的页地址流,并针对不同的算法计算出相应的命中率。
相关定义如下:
1数据结构
(1)页面类型
typedefstruct(
intpn,pfn,counter,time;
}pl-type;
其中pn为页号,pfn为面号,counter为一■个周期内访问该页面的次数,time为访问时间.
(2)页面控制结构
pfc-struct{
intpn,pfn;
structpfc_struct*next;
}
typedefstructpfc_structpfc_type;
pfc_typepfc_struct[total_vp],*freepf_head,*busypf_head;
pfc_type*busypf_tail;
其中pfc[total_vp]定义用户进程虚页控制结构,
*freepf_head为空页面头的指针,
*busypf_head为忙页面头的指针,
*busypf_tail为忙页面尾的指针.
2.函数定义
(1)Voidinitialize():
初始化函数,给每个相关的页面赋值.
(2)VoidFIFO():
计算使用FIFO算法时的命中率.
(3)VoidLRU()
(4)Void0PT()
(5)VoidLFU()
(6)VoidNUR()
计算使用LRU算法时的命中率.计算使用OPT算法时的命中率.计算使用LFU算法时的命中率.计算使用NUR算法时的命中率.
3.变量定义
(1)inta[total_instruction]:
指令流数据组.
(2)intpage[total_instruction]:
每条指令所属的页号.
(3)intoffset[total_instruction]:
每页装入10条指令后取模运算页号偏移值.
(4)inttotal_pf:
用户进程的内存页面数.
(5)intdisaffect:
页面失效次数.
4.程序参考源码及结果
〈程序〉
ftincludeftincludeftincludeftdefineTRUE1
ftdefineFALSE0
ftdefineINVALID-1
ftdefineNUL0#definetotal_instruction320/*指令流长*/
ftdefinetotal_vp32/*虚页长*/
#defineclearperiod50/*清零周期*/
typedefstruct(/*页面结构*/
intpn,pf