操作系统实验参考.docx
《操作系统实验参考.docx》由会员分享,可在线阅读,更多相关《操作系统实验参考.docx(59页珍藏版)》请在冰豆网上搜索。
操作系统实验参考
实验一熟悉Linux/UNIX操作系统
[实验目的]:
1.熟悉Linux/UNIX操作系统的基本操作。
2.掌握常用基本命令和系统调用。
[实验内容]:
1.学会开机、登录、退出与关机
(1)开机
很多时候,一台机器上会安装多个操作系统(OperatingSystem,简称OS),因此,在开机时会让用户选择进入哪个OS。
例如,显示“LinuxLILO:
”,或在Windows2000平台下的菜单选择OS。
选择进入Linux后,Linux初始化过程中会显示大量初始化信息,要求学习者逐渐读懂这些初始化信息,以从这个角度来理解Linux的工作原理。
(2)登录与修改口令
在打开终端或在Neterm之类的程序上进行远程连接后,Linux/UNIX在相应初始化完成后,会在屏幕上显示“login:
”。
此时输入用户名(帐号)并键如回车,则系统显示“password:
”,然后输入保密字(口令)并键入回车。
此时,系统验证所键入的用户名和保密字,若正确则成功进入系统,显示命令提示符#,若不正确则显示“loginincorrect”,并重新显示“login:
”,让用户重新输入正确的用户名和保密字。
有时用户可能想修改保密字,则可以在成功进入系统后,在命令提示符后输入“password”并键入回车,则系统再显示“newpassword:
”。
当用户键入新保密字并键入回车后,系统再显示“retypenewpassword:
”,此时需再次重复键入刚才输入的新保密字并键入回车,则系统接收并记住新的保密字。
如果用户在登录时忘了保密字,则只能找系统管理员解决问题。
或者,如果用户想修改自己的用户名,也只能找系统管理员解决。
(3)退出、注销
当用户不再使用Linux/UNIX时,在离开前,通常应键入logout命令或ctrk+D开退出帐号。
若是在PC上安装Linux/UNIX下,则此步骤可以省略而键入halt或reboot命令。
若是在多用户机器上(终端/网络登录),则此步骤最好不要略过,否则会导致计帐或安全上的问题。
(4)关机或重启
在Linux/UNIX下,涉及到关机或重启的命令有:
a)键入halt命令。
这是最常用的关机方式。
b)如果用户只是想退出Linux操作系统,并不想关机,还想再进入其他OS(例如Windows),则键入reboot命令(重启)。
c)在多用户机器上,系统管理员在关机(键入halt命令)前,通常要键入shutdown命令。
这是一条广播性质的命令,通知各用户即将关机,以便给各用户留下一定的时间作保存、退出等工作。
d)在窗口工作方式下,可以通过与Windows类似的开始菜单来关机或重启:
“开始”—“关闭系统”—“关机或重启”—……。
2.窗口工作方式与中断工作方式
早期的UNIX版本都是传统的终端工作方式,这种工作方式在系统启动后就显示命令提示符,没有多个窗口。
随着Macintosh和Windows这样的窗口界面的出现和普及,UNIX和Linux开始引入窗口工作方式。
UNIX和Linux下的窗口平台都基于X-Windows,有KDE窗口平台,GNOME窗口平台、SUNOpenWindows窗口平台等。
用户登录后就进入终端工作方式,用户可以在终端工作方式下键入“starts”命令进入窗口工作方式。
进入窗口工作方式后,可以按Ctrl+Alt+F2进入终端工作方式,之后可按Ctrl+Alt+F7再从终端工作方式回到窗口工作方式。
窗口工作方式与在Windows下的工作方式类似,可以在桌面上开多个窗口。
Linux/UNIX窗口工作方式下,一个窗口可以对应一个进程,也可以对应多个进程,例如一个Shell窗口(类似与Windows下的DOS窗口)。
3.常用命令/系统调节列表
表1.1给出了Linux/UNIX各章实验开始前必须掌握的最基本的常用命令。
表1.2给出了Linux/UNIX下各章实验开始前必须掌握的最基本和常用的系统调用。
表1.1Linux/UNIX各章实验开始前必须掌握的基本常用命令
命令名
功能
Rs
显示进程状态
Kill
给进程发信号,杀死进程
Rm
删除文件或目录(removefilesordirectories)
Cp
复制文件和目录(copyfilesanddirectories)
Cat
将指定文件(或标准输入)内容输出至标准输出(通常的用途是显示文件内容),当输入文件为多个时则为合并输出(concatenatefilesandprintonstandardoutput)
More
文件分页显示的交互式工具(filesperusalfilterforcrtviewing)
Ls
显示文件属性和目录内容
Chmod
改变文件访问权限(changefileaccesspermissions)
mkdir
建立目录(makedirectories)
Pwd
显示当前目录名/工作目录名(printnameofcurrent/workingdirectory)
Echo
显示一行(displayalineoftext)
chear
清屏(cleartheterminalscreen)
表1.2Linux/UNIX各章实验开始前必须掌握的基本常用系统调用
名称
功能
Open,
creat
打开和/或建立一个文件或设备
(openandpossiblycreateafileordevice)
Close
关闭一个文件描述字(closeafiledescriptor)
Read
读文件(readfromafiledescriptor)。
对于一个已打开的文件,通过它的文件描述字,读该文件的内容
Write
写文件(writetoafiledescriptor)。
对于一个已打开的文件,通过它的文件描述字,写该文件的内容
Lseek
改变文件内当前读写指针位置(repositionread/writefileoffset)
4.外存目录树结构
以Linux2.2版为例,外存目录树结构如图1.1所示。
图中,Linux命令实用程序放在/bin和/usr/bin下,源码放在/usr/src下,内核程序文件vmlinux放在/boot下,设备特别文件放在/dev下,帮助文件放在/usr/man下,用户主目录通常放在/home下……
/
rootbinbootdevhomelibmnfprocusr
binsrcmanlib
图1.1Linux外存目录树结构
5.程序开发工具:
编辑、编译、连接、调试
i.编辑程序
Linux/UNIX的编辑程序有Emacs、vi、ed等。
笔者建议使用Emacs.
ii.编译程序
编译、调试C程序时,可以在Emacs中编译,也可以在命令行下编译:
#ccf.c
上述命令行编译C源程序f.c,输出的可执行目标程序为a.out。
#ccf.c–of
上述命令行编译C源程序f.c,输出的可执行目标程序为f。
#cc–cf.c
上述命令行编译C源程序f.c,但只输出目标模块f.o。
iii.调试程序
Linux下的常用调试程序是GDB。
此外,ptrace系统调用(跟踪进程执行)、strace命令(跟踪系统调用与信号)、Ltrace命令(跟踪库函数调用,alibrarycalltracer)等,也可以用来辅助调试。
iv.make程序
如果所编制的程序由几十个模块组成,修改其中任一模块时都要将这几十个模块重新连接,则此时make可以大大提高工作效率,减少很多重复性劳动。
6.SHELL
Linux/UNIX的命令解释器俗称SHELL,具有以下两个功能:
(1)显示命令提示符,接收、解释、启动执行命令行。
(2)解释执行批处理文件(Shellscript),提供很多内部命令和大量命令组合功能。
Linux/UNIX下的SHELL有很多种,有CSH、BSH、KSH等。
7.如何获得帮助信息和技术资料
(1)联机帮助命令man、info和—help选项
例如,要查询cat命令的功能和用法,键入以下3个命令行中的任意一个即可。
#mancat
#infocat
#cat–help
man命令提供的联机帮助信息有8节,分别对应以下内容:
man1命令
man2系统调用
man3库函数
man4设备驱动程序和设备特别文件
man5系统文件
man6游戏
man7宏程序包和语言约定
man8系统管理和维护工具
(2)其他帮助
这包括厂家提供的手册、市场上销售的各种参考书,各种网上资源等。
此外,有些窗口平台带有联机帮助菜单项。
实验二进程的创建和控制
[实验目的]:
(1)加深对进程概念的理解,明确进程和程序的区别。
(2)进一步认识并发执行的实质。
(3)加深对进程管理概念的理解。
(4)分析进程的创建过程。
[实验预备内容]:
(1)阅读Linux的fork.c源码文件。
(2)a.Linux/UNIX的进程和CPU管理类命令:
(8个)
命令名
功能
Ps
显示进程状态
Pstree
显示进程树(displayatreeofprocesses)
Kill
给进程发信号
Killhall
按名给进程发信号(killprocessesbyname)
Skill,snice
报告进程状态(reportprocessstatus)
Top
显示进程状态(displaytopCPUprocesses)
Procinfo
显示从/proc搜集的系统状态信息
Idle
使进程0进入idle状态(makeprocess0idle)
b.Linux/UNIX进程和CPU管理类系统调用:
类别
个数
列举
进程建撤与状态改变
13
Fork(),clone(),vfork(),execve(),exit(),nanosleep(),
pause(),wait(),waitpid(),wait4(),wait3(),kill(),killpg()
进程调度优先级管理
11
Getpriority,setpriority,nice,sched_get_priority_max,sched_get_priority_min,
Sched_setparam,sched_getparam,sched_setscheduler,sched_getscheduler,sched_rr_get_interval,sched_yield
进程号(组)的设置与查看
7
Getpid,getppid,setpgid,getpgid,setpgrp,getpgrp,setsid
进程跟踪调试和进程运行时间
2
Ptrace(),times
其他与进程/CPU管理相关的系统调用
6
Personality,vm86,prctl,acct,idle,vm86old
c.Linux/UNIX进程和CPU管理类系统调用
(1):
与进程建撤和状态有关的系统调用(13个)
名/格式/参数
功能
参数/返回值的解释
其他说明
fork(),
vfork()
建立一个子进程
(createachildprocess)
对父进程:
返回子进程号。
对子进程:
返回0
不成功:
返回-1
Linux2.2下,vfork只是fork的一个别名而已,两者完全相同。
而在UNIX下两者则有所区别。
intclone(int(*fn)
(void*arg),
Void*childstack,intflags,void*arg)
建立一个子进程(creatachildprocess)
仅在Linux下有。
intexecve(constchar*filename,
char*constargv[],char*constenvp[]);
执行程序(executeprogram)
功能:
用指定程序覆盖当前程序代码
返回:
成功与否
在库函数级对应execle,execlp,execl,execv,execvp五个函数。
参见man3
_exit
terminatethecurrent
process
终止当前进程
nanosleep
pause
executionforaspecifiedtime
暂停执行指定的一段时间
wait,waitpid
waitforprocess
termination
等待进程终止
wait3,wait4
waitforprocess
Termination,
BSDtyle
BSD风格的等待进程终止
kill
sendsignaltoaprocess
向一个进程发信号
killpg
sendsignaltoaprocessgroup
向一个进程组发信号
pause
waitforsignal
等待信号
d.Linux/UNIX进程和CPU管理类系统调用
(2)与进程号/组有关的系统调用(7个)
名/格式
功能
Getpid,
getppid
获得进程号(getprocessidentification)
Setpgid,
getpgid,
setpgrp,
getpgrp
设置/查询进程组(set/getprocessgroup)
setsid
建立一个会话并设置进程组号
(createsasessionandsetstheprocessgroupID)
e.Linux/UNIX进程和CPU管理类系统调用(3):
与进程调度有关的系统调用(11个)
名/格式
功能
getpriority,setpriority
设置/查看程序调度优先级
(get/setprogramschedulingpriority)
nice
改变进程优先级(changeprocesspriority)
sched_get_priority_max,
sched_get_priority_min
设置静态优先级范围(getstaticpriorityrange)
sched_setparam,sched_getparam
设置/查看调度参数
(setandgetschedulingparameters)
sched_setscheduler,sched_getscheduler
设置/查看调度算法和参数
(setandgetschedulingalgorithm/parameters)
sched_rr_get_interval
查看指定进程的SCHED_RR值(gettheSCHED_RRintervalforthenamedprocess)
f.Linux/UNIX进程管理类系统调用(4):
与进程跟踪/进程运行时间有关的系统调用(2个)
名/格式
功能
ptrace
进程跟踪(processtrace)
times
得到进程时间(getprocesstimes)
g.Linux/UNIX进程和CPU管理类系统调用(5):
其他与进程和CPU管理有关的系统调用(6个)
名/格式
功能
prctl
进程控制(operationsonaprocess)
personality
设置进程执行域(settheprocessexecutiondomain)
acct
开/关进程记帐(switchprocessaccountingonoroff)
idle
使进程0进入idle状态(makeprocess0idle)
vm86old,vm86
进入虚拟8068方式(entervirtual8068mode)
h.Linux线程库常用函数
函数名
功能
pthread_create
建立一个新线程
pthread_cancel,pthread_setcancelstate,
pthread_setcanceltype,pthread_testcancel
线程撤消(threadcancellation)
pthread_join
等待另一线程终止
pthread_exit
退出当前线程
pthread_sigmask,pthread_kill,sigwait
线程中的信号处理
[实验内容]:
(1)进程的创建
编写一段程序,使用系统调用fork()创建两个子进程。
当此程序运行时,在系统中有一个父进程和两个子进程活动。
让每一个进程在屏幕上显示一个字符:
父进程显示字符“a”;子进程分别显示字符“b”和字符“c”。
试观察记录屏幕上的显示结果,并分析原因。
<程序>
#include
main()
{
intp1,p2;
while((pl=fork())==-1);/*创建子进程p1*/
if(pl==0)/*子进程创建成功*/
putchar(‘b’);
else
{
while((p2=fork())==-1);/*创建另一个子进程*/
if(p2==0)/*子进程创建成功*/
putchar(‘c’);
elseputchar(‘a’);/*父进程执行*/
}
}
<运行结果>
bca(有时会出现bac)
分析:
从进程并发执行来看,输出bac,acb等情况都有可能。
原因:
fork()创建进程所需的时间要多于输出一个字符的时间,因此在主进程创建进程2的同时,进程1就输出了“b”,而进程2和主程序的输出次序是有随机性的,所以会出现上述结果。
(2)进程的控制
修改已编写的程序,将每个进程输出一个字符改为每个进程输出一句话,在观察程序执行时屏幕上出现的现象,并分析原因。
如果在程序中使用系统调用lockf()来给每一个进程加锁,可以实现进程之间的互斥,观察并分析出现的现象。
<程序1>
#include
main()
{
intpl,p2,i;
while((p1=fork())==-1);
if(p1==0)
for(i=0;i<500;i++)
printf("child%d\n”,i);
else
{
while((p2=fork())==-1);
if(p2==0)
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()输出的字符串之间不会被中断,因此,字符串内部的字符顺序输出时不变。
但是,由于进程并发执行时的调度顺序和父子进程的抢占处理机问题,输出字符串的顺序和先后随着执行的不同而发生变化。
这与打印单字符的结果相同。
<程序2>
#include
main()
{
intp1,p2,i;
while((pl=fork())==-1);
if(pl==0)
{
lockf(1,1,0),
for(i=0;i<500;i++)printf((“child%d/n”,i);
lockf(1,0,0);
}
else
{
while((p2=fork())==-1);
if(p2==0)
{
lockf(1,1,0);
for(i=0;i<500;i++)printf(“son%d\n”,i);
lockf(1,0,0);
}
else
{
lockf(1,1,0);
for(i=0;i<500;i++)printf(“daughter%d\n”,i);
lockf(1,0,0);
}
}
}
<运行结果>
大致与未上锁的输出结果相同,也是随着执行时间不同,输出结果的顺序有所不同。
分析:
因为上述程序执行时,不同进程之间不存在共享临界资源(其中打印机的互斥性已由操作系统保证)问题,所以,加锁与不加锁效果相同。
实验三实现进程的软中断通信
[实验目的]:
1.掌握基本的软中断通信方法。
2.利用系统调用signal()捕捉中断信号。
3.理解Linux系统中的进程通信的基本原理。
[实验内容]:
(1)编制一段程序,使其实现进程的软中断通信。
要求:
使用系统调用fork()创建两个子进程,再用系统调用signal()让父进程捕捉键盘上来的中断信号(即按^C键);当捕捉到中断信号后,父进程用系统调用Kill()向两个子进程发出信号,子进程捕捉到信号后分别输出下列信息后终止:
ChildProcessllisKilledbyParent!
ChildProcessl2isKilledbyParent!
父进程等待两个子进程终止后,输出如下的信息后终止:
ParentProcessisKilled!
(2)在上面的程序中增加语句signal(SIGINT,SIG_IGN)和signal(SIGQUIT,SIG_IGN),观察执行结果,并分析原因。
这里,signal(SIGINT,SIG_IGN)和signal(SIGQUIT,SIG_IGN)分别为忽略Del键信号以及忽略中断信号。
<任务1程序>
#include
#include
#include
voidwaiting(),stop();
intwait_mark;
main()
{
intpl,p2,stdout;
while((p1=fork())==-1);/*创建进程p1*/
if(p1>0)
{
while((p2=fork())==-1);
if(p2>0)
{
wait_mark=1;
signal(SIGINT,stop);/*接收Del信号,并转stop*/
waiting(0);
kill(p1,16);/*向p1发中断信