《操作系统》实验指导书6.docx
- 文档编号:8237120
- 上传时间:2023-01-30
- 格式:DOCX
- 页数:78
- 大小:727.89KB
《操作系统》实验指导书6.docx
《《操作系统》实验指导书6.docx》由会员分享,可在线阅读,更多相关《《操作系统》实验指导书6.docx(78页珍藏版)》请在冰豆网上搜索。
《操作系统》实验指导书6
《操作系统》
实验指导书
(课程编号:
408015、420013、436016)
主撰人:
羊四清
审核人:
湖南人文科技学院计算机科学技术系
2012年6月
目录
前言1
实验一:
安装ubuntu10.04与Linux下C语言程序开发过程3
一、实验目的3
二、实验主要设备及使用要求3
三、实验原理、方法和手段3
四、实验内容与步骤3
五、思考题8
实验二进程与线程的用法9
一、实验目的9
二、实验主要设备及使用要求9
三、实验原理或算法9
四、实验内容与步骤10
五、思考题17
实验三进程调度19
一、实验目的19
二、实验主要设备及使用要求19
三、实验原理或算法19
四、程序清单20
五、思考题27
实验四生产者消费者问题的实现28
一、实验目的28
二、实验主要设备及使用要求28
三、实验原理或算法28
四、程序清单29
五、思考题32
实验五银行家算法34
一、实验目的34
二、实验主要设备及使用要求34
三、实验原理或算法34
四、程序清单35
五、思考题41
实验六连续存储分配管理41
一、实验目的41
二、实验主要设备及使用要求41
三、实验原理或算法41
四、程序清单42
五、实验思考53
实验七页面置换算法54
一、实验目的54
二、实验主要设备及使用要求54
三、实验原理或算法54
四、程序清单55
五、思考题63
实验八磁盘调度算法64
一、实验目的64
二、实验主要设备及使用要求64
三、实验原理或算法64
四、程序清单66
五、思考题72
前言
1.实验总体目标
通过本实验课程,应达到以下教学目的:
(1)对操作系统的发展过程、功能结构、特征和发展趋势有清晰的了解。
(2)掌握进程和线程的创建、撤消和运行,进程调度、进程通信、死锁检测等基本方法。
(3)掌握内存空间的分配与回收、分页系统中的页面转换算法的基本原理与实现方法。
(4)掌握磁盘的调度与管理方法。
(5)通过模拟文件管理的工作过程,了解文件操作命令的实质。
(6)了解网络操作系统的功能和特征。
(7)具备分析和设计操作系统基本算法的能力。
(8)通过实验养成良好的理论联系实际、自己动手操作的习惯,以获得项目管理和团队协作的实际训练和具体经验。
2.适用专业
计算机科学与技术、网络工程、软件工程
3.实验课时分配
实验序号
实验项目名称
实验要求
实验类型
每组人数
实验
学时
实验一
安装ubuntu10.0与Linux下C语言程序开发过程
必做
验证
1
2
实验二
进程与线程的用法
必做
验证
1
2
实验三
进程调度
必做
综合
1
2
实验四
生产者消费者问题的实现
必做
设计
1
2
实验五
死锁检测
必做
综合
1
2
实验六
连续存储分配管理
必做
验证
1
2
实验七
页面置换算法
必做
综合
1
2
实验八
磁盘臂调度算法
必做
综合
1
2
4.实验环境
计算机、Linux操作系统、VC6.0
5.实验总体要求
要求掌握流行操作系统的基本使用与管理操作,并学会用高级程序设计语言设计有关进程创建、进程调度、进程通信、死锁以及存储管理、设备管理、文件管理等主要算法的模拟程序。
上机实验要求:
1、准备好上机所需的程序;
2、上机输入和调试自己所编写的程序;
3、上机结束后,应整理出实验报告,实验报告应包括以下内容:
实验项目名称;算法分析;程序清单;运行结果;对运行情况所作的分析以及本次调试程序所取得的经验,如果程序未能通过,应分析其原因。
6.本课程的重点、难点及教学方法建议
本实验课程的重点进程的创建与应用、几种典型的算法,如进程调度、死锁、存储管理、设备管理等,难点是进程之间的通信与实现。
建议采用的教学方法:
(1)上机实验法:
通过上机实验完成各个实验内容。
(2)学中做:
由教师给出各实验的演示程序,并进行讲解,然后学生根据讲解内容与参考程序在学习的基础上自己独立完成实验任务
(3)实验结果分析法:
对实验结果或运行异常情况进行分析,分析产生各种现象的原因,并解决问题。
实验一:
安装ubuntu10.04与Linux下C语言程序开发过程
一、实验目的
掌握ubuntu10.04版Linux操作系统的安装过程与操作系统的系统配置,安装完系统后熟悉Linux操作系统下C语言程序的开发过程,包括编辑、编译、调试过程。
二、实验主要设备及使用要求
按操作计算机的要求使用好计算机设备。
三、实验原理、方法和手段
原理与方法:
按ubuntu10.04版系统要求配置好计算机,并按操作步骤进行系统的安装。
然后按照C语言编程方法编写基本的C语言程序,使用gcc命令进行程序的编译,运行编译后的可执行文件。
实验手段:
上机操作
四、实验内容与步骤
(一)ubuntu10.04版系统的安装
Ubuntu系统ISO安装包中自带了一个wubi.exe程序,利用它可以轻松在Windows安装ubuntu,不用刻盘,不用重新分区,分区无论是NTFS还是FAT32都可以安装,而且安装前不用拔网线,它在安装过程中在需要下载语言包时可以选择跳过。
安装需要最少有3G的硬盘空间。
不用特意空一个盘来安装,就好像普通软件一样,可以简单安装删除卸载等操作。
是新手学习ubuntu系统非常好的安装方法。
软件下载:
UbuntuDesktop10.04LTS(32位)下载地址:
1、基本背景知识介绍
Ubuntu的一大好处就是可以在windows系统下安装,非常简便,安装之后可以和原有的windows系统组成双系统,如果需要删除Ubuntu可以在windows下像删除普通程序一样删除。
Wubi(基于Windows的安装程序,Windows-basedUbuntuInstaller)是使用GPL协议进行发布的一个Ubuntu自由软件安装程序,并得到了Ubuntu的官方支持。
这个项目的目标是帮助不熟悉Linux的Windows用户在试用Ubuntu时,无需对硬盘进行格式化或重新分区。
Wubi也可以在Windows里对Ubuntu进行卸载。
Wubi并不是虚拟机,但它会在一个虚拟设备中创建一个独立的安装。
Wubi本身也不是一个Linux发行版而只是Ubuntu的一个安装程序。
Wubi会在Windows的启动菜单中添加一个项目来允许你运行Linux。
Ubuntu安装在Windows文件系统的一个文件中(c:
\ubuntu\disks\root.disk),而不是单独的分区中。
这个文件在Linux下被视为真实的硬盘。
2、安装步骤
(1)把下载的ISO重命名成installation.iso和wubi.exe放在同一文件夹下面放在你想装的盘中,建议盘空间有10G以上的剩余空间。
(2)双击wubi.exe设置你要装的盘的空间大小(建议使用10G以上),设置用户名和密码,如果从安全性考虑建议密码设长点,然后记住它,一定要记牢,但不设也没有关系。
(3)安装程序展开Ubuntu,然后开始安装(这个过程大概不到三分钟)
(4)点击Finish后重启,进入启动选项界面可以看到两个选项windoswsXP和Ubuntu,选择Ubuntu就可以继续安装,大概十分钟左右可以安装完成。
到这一步,基本操作系统就安装好了,可以进入Ubuntu桌面了。
接下来就是安装软件,一般用sudoapt-getinstall(软件名)命令进行安装。
注意:
安装过程中最好把网线拔了不然你安装就要安装很久了(因为它会自动会下载一些语言包等,如果网线没有拨掉,你也可以选择进度条右下方的Skip,直接跳过,节省时间)点开始安装就可以直接安装。
(5)安装好后进入桌面后就可以开始上网了,前提是网络连接正常了。
可以在终端用ping命令检查网络是否连接正常,然后点屏幕左上角的火狐,就可以开始上网。
(6)如第四步中没有安装语言包,进入桌面后可以再安装。
点窗口左上角的----system----展开----administration-----点击-----languagesupport直接看到窗口最下面的install/removelanguages,找到里面的chinese(simplified)后面打勾然后点下面到Components里面能打勾到全打勾tranlations最后点applychanges等他更新完毕,然后在keepthesame前面打勾,在选项里面选中chinese(simplified)。
(若在安装过程中安装了语言包的有汉语(中国)就点他)完成后重启在重启时注意在的启动界面选择语言选中文就成为中文版的Ubuntu系统了。
3、安装完成后网络配置
(1)ADSL配置:
打开终端,输入sudopppoeconf然后一路回车(默认选项就可以),填写用户名时须注意,要先将usrname这个词删掉,再添上用户名,然后填上密码,再一路回车就可以了。
以后每次开机时都会自动连接上。
(2)无线网络配置:
在wpa模式下配置使用无线网络。
①、安装wpa_supplicant
apt-getinstallwpasupplicant
②、创建/etc/wpa_supplicant.conf包含以下内容:
network={
ssid="你的无线网ssid"
psk="你的wpa口令"
key_mgmt=WPA-PSK
proto=WPA
pairwise=TKIP
}
③、编辑/etc/network/interfaces
ifaceeth1inetdhcp
pre-upwpa_supplicant-Bw-Dwext-ieth1-c/etc/wpa_supplicant.conf
post-downkillall-qwpa_supplicant
注:
eth1是你的网卡,并且假设你使用dhcp协议。
④、启动你的网卡
ifupeth1
如果有必要请关闭你的有线网络(ifdowneth0),防止路由问题。
(二)Linux操作系统下C语言程序的开发过程
1.Linux的操作系统下终端命令方式
这里讨论的都是通过shell命令行进行操作的。
那如果进入了图形界面的Linux怎么办呢?
只要打开一个终端命令,就和命令行环境完全一样了(打开开始菜单可以找到终端命令)。
2.必备的开发工具:
1)输入程序需要一个编辑器。
常用的有vi,emacs.在命令行上输入vi,emacs,…就可进入编辑环境
2)C语言的编译器。
常用的是GNU的c语言编译器gcc(编译C程序),g++(编译C++程序)。
3)调试程序的常用工具:
gdb.
关于Linux的文档是非常丰富的。
最快捷,方便,全面的资料就在你的机器里,不要浪费。
在命令行上输入shell命令man或者info:
$mangcc
3.基本步骤:
(1)输入源代码
(2)编译,链接,运行
(3)调试程序
以最基本的helloworld程序开始,操作过程如下:
(1)输入源代码
引用
$emacshello.c
#include
intmain()
{
printf(“HelloWorld.\n”);
return0;
}
完成输入后,按住CTR+x+c,最后松开CTRL。
程序保留并退出emacs环境。
(2)编译,链接,运行
引用
$gcc–ohellohello.c
$./hello
HelloWorld.
$
一个linux平台上的c程序开发已经完成
(3)调试
如果要使用gdb调试程序,那么在上一步编译的时候,记得加上–g选项
引用
$gcc–g–ohellohello.c
$gdbhello
五、思考题
1、自己上网浏览linux操作系统的使用方法
2、查阅gcc,gdb命令的参数格式与功能
实验二进程与线程的用法
一、实验目的
掌握fork()、vfork()进程创建函数的使用方法,理解其执行过程。
掌握pthread_creat()线程创建、pthread_join()线程等待函数的使用方法。
进一步熟悉Linux操作系统下C语言程序的开发过程。
二、实验主要设备及使用要求
按操作计算机的要求使用好计算机设备。
三、实验原理或算法
原理与方法:
1.fork()函数定义:
pid_tfork(void);
(pid_t是一个宏定义,其实质是int被定义在#include
返回值:
若成功调用一次则返回两个值,子进程返回0,父进程返回子进程ID;否则,出错返回-1.
函数说明:
一个现有进程可以调用fork函数创建一个新进程。
由fork创建的新进程被称为子进程(childprocess)。
fork函数被调用一次但返回两次。
两次返回的唯一区别是子进程中返回0值而父进程中返回子进程ID。
子进程是父进程的副本,它将获得父进程数据空间、堆、栈等资源的副本。
注意,子进程持有的是上述存储空间的“副本”,这意味着父子进程间不共享这些存储空间。
linux将复制父进程的地址空间内容给子进程,因此,子进程有了独立的地址空间。
2.fork()函数定义:
pid_tfork(void);
返回值:
如果vfork()成功则在父进程会返回新建立的子进程代码(PID),而在新建立的子进程中则返回0。
如果vfork()失败则直接返回-1,失败原因存于errno中。
函数说明:
vfork()会产生一个新的子进程.但是vfork创建的子进程与父进程共享数据段,而且由vfork创建的子进程将先于父进程运行.
vfork()用法与fork()相似.但是也有区别,具体区别归结为以下3点:
1.fork():
子进程拷贝父进程的数据段,代码段vfork():
子进程与父进程共享数据段.
2.fork():
父子进程的执行次序不确定.
3.vfork():
保证子进程先运行,在调用exec或exit之前与父进程数据是共享的,在它调用exec或exit之后父进程才可能被调度运行。
如果在调用这两个函数之前子进程依赖于父进程的进一步动作,则会导致死锁。
3.pthread_create()函数定义:
头文件:
#include
intpthread_create(pthread_t*thread,pthread_addr_t*attr,void*(*start_rtn)(void*),void*arg);
参数:
∙thread :
用于返回创建的线程的ID
∙attr :
用于指定的被创建的线程的属性,上面的函数中使用NULL,表示使用默认的属性
∙start_rtn :
这是一个函数指针,指向线程被创建后要调用的函数
∙arg :
用于给线程传递参数,在本例中没有传递参数,所以使用了NULL
返回值
若成功则返回0,否则返回出错编号
返回成功时,由thread指向的内存单元被设置为新创建线程的线程ID。
attr参数用于制定各种不同的线程属性。
新创建的线程从start_rtn函数的地址开始运行,该函数只有一个万能指针参数arg,如果需要向start_rtn函数传递的参数不止一个,那么需要把这些参数放到一个结构中,然后把这个结构的地址作为arg的参数传入。
编译的含有线程的程序时候,一定要加上-lpthread选项,否则会报错。
4.pthread_join()函数定义:
头文件:
#include
函数原型为:
intpthread_join(pthread_tthread,void**retval);
第一个参数为被等待的线程标识符,第二个参数为一个用户定义的指针,它可以用来存储被等待线程的返回值。
这个函数是一个线程阻塞的函数,调用它的函数将一直等待到被等待的线程结束为止,当函数返回时,被等待线程的资源被收回。
如果执行成功,将返回0,如果失败则返回一个错误号。
pthread_join使一个线程等待另一个线程结束。
代码中如果没有pthread_join主线程会很快结束从而使整个进程结束,从而使创建的线程没有机会开始执行就结束了。
加入pthread_join后,主线程会一直等待直到等待的线程结束自己才结束,使创建的线程有机会执行。
所有线程都有一个线程号,也就是ThreadID。
其类型为pthread_t。
通过调用pthread_self()函数可以获得自身的线程号。
实验手段:
上机操作
四、实验内容与步骤
程序一:
fork()入门
#include
#include
#include
intmain()
{
pid_tpid;
pid=fork();
if(pid<0)
printf("errorinfork!
");
elseif(pid==0)
printf("childprocess,IDis%d\n",getpid());
else
printf("parentprocess,IDis%d\n",getpid());
}
gcctest1.c-otest1
debian:
/tmp#./test1
Iamthechildprocess,IDis2723
Iamtheparentprocess,IDis2722
程序分析:
主进程子进程(主进程的副本,)
程序运行时,产生的进程称为父进程,当执行到fork()函数时,便创建了一个子进程,同时子进程将获得父进程数据空间、堆、栈等资源的副本(父子进程间不共享这些存储空间),但子进程仅从运行fork()的代码,而父进程运行全部代码。
1)pid=fork();
操作系统调用fork()函数创建一个新的进程(子进程),并且在进程表中相应为它建立一个新的表项,此时子进程得到CPU的调度,它的上下文被换入,占据CPU,操作系统对fork的实现,使得子进程中fork调用返回0,所以在这个进程中pid=0,这个进程继续执行的过程中,if语句中pid<0不满足,但是pid==0是true。
所以输出iamthechildprocess,IDis2723(此处2723是子进程本身的ID)
操作系统对fork的实现,使这个调用在父进程中返回刚刚创建的子进程的pid(一个正整数),所以下面的if语句中pid<0,pid==0的两个分支都不会执行。
所以输出iamtheparentprocess,IDis2722(此处2723是父进程本身的ID)
2)对子进程来说,fork返回给它0,但它的pid绝对不会是0,之所以fork返回0给它,是因为它随时可以调用getpid()来获取自己的pid
3)fork之后父子进程除非采用了同步手段,否则不能确定谁先运行,也不能确定谁先结束.认为子进程结束后父进程才从fork返回的,这是不对的,fork不是这样的,vfork才这样。
4)父进程执行了所有的进程,而子进程只执行了fork()后面的程序,这是因为子进程继承了父进程的PC(程序计数器).
程序二:
fork的另一个例子:
#include
#include
#include
intmain()
{
pid_tpid1;
pid_tpid2;
pid1=fork();
pid2=fork();
printf("pid=%d,pid1:
%d,pid2:
%d\n",getpid(),pid1,pid2);
}
编译:
gcctest2.c-otest2
运行:
./test2
pid=21340,pid1:
21341,pid2:
21342pid=21341,pid1:
0,pid2:
21343pid=21343,pid1:
0,pid2:
0pid=21342,pid1:
21341,pid2:
0 程序分析:
1)执行test2时,启动一个进程,设这个进程为P0,PID为21340.(运行时可能不同)
2)当执行到pid1=fork();时,P0启动了一个进程,设这个进程为P1,它的PID为21341,暂且不管P1.
3)P0中的fork返回21341给pid1,继续执行到pid2=fork();此时启动另一个新的进程,设为P2,P2的PID为21342,同样暂且不管P2.
4)P0的第二个fork返回21342给p2,最后P0的执行结果为pid=21340,pid1:
21341,pid2:
21342
5)再看P2,P2生成时,P0中的pid1=21341,所以P2中的pid1继承P0的pid1=21341,而作为子进程pid2=0,P2从第二个fork后开始执行,
最后输出pid=21342,pid1:
21341,pid2:
0 6)回头看P1,P1中第一条fork返回0给pid1,然后接着执行后面的语句.而后面接着的语句是pid2=fork();执行到这里,P1又产生了一个新进程,设为P3,先不管P3.
7)P1中第二条fork将P3的PID返回给pid2,P3的PID为21343,所以P1的pid2=21343。
P1继续执行后续程序,结束,输出pid=21341,pid1:
0,pid2:
21343
8)P3作为P1的子进程,继承P1中pid1=0,并且第二条fork将0返回给pid2,所以P3最后输出“pid=21343,pid1:
0,pid2:
0”.
9)所有的进程都执行完毕.
其进程创建如下图:
程序三:
vfork()
vfork保证子进程先运行,在它调用exec或exit之后父进程才可能被调度运行.如果在调用这两个函数之前子进程依赖于父进程的进一步动作,则会导致死锁.
#include
#include
#include
intmain(void)
{
pid_tpid;
intcount=0;
pid=vfork();
if(pid==0)
{
count++;
_exit(0);
}
else
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 操作系统 实验 指导书
![提示](https://static.bdocx.com/images/bang_tan.gif)