操作系统试验手册基于Linux.docx
- 文档编号:11616774
- 上传时间:2023-03-28
- 格式:DOCX
- 页数:38
- 大小:57.42KB
操作系统试验手册基于Linux.docx
《操作系统试验手册基于Linux.docx》由会员分享,可在线阅读,更多相关《操作系统试验手册基于Linux.docx(38页珍藏版)》请在冰豆网上搜索。
操作系统试验手册基于Linux
试验一Linux操作系统的编译和执行环境——终端Shell
一.背景知识:
在Linux操作系统中Shell是操作系统外壳。
它不但是用户与操作系统交互的命令解释器,还是一个具有环境个性化的程序设计语言。
二.试验目的:
1、了解操作系统的编程环境,文本程序编辑器和程序的编译执行环境Shell。
2、了解Shell的几个常用的命令。
3、编写简单的C语言程序,并在Shell环境下编译,执行。
三.实验原理或流程图
高级语言程序必须先编译,才能执行。
命令为:
cc–o参数1参数2,参数2是已经写好的C语言源程序,参数1是要生成的可执行文件名,任意写文件名就行,不用扩展名。
四.实验内容
1、熟练使用Linux常用的几个终端命名。
2、掌握Linux环境下,编程->编译->执行,这三个程序的运行过程。
五.试验步骤:
1、打开Linux的应用程序—>附件—>终端,就可以打开Shell命令解释环境。
2、熟悉几个重要的Shell命令。
在Shell终端中输入以下命令,查看结果,理解命令的功能。
(1)echo”thisismyfirstcommandofLinux”
说明echo的功能:
_____________________________。
(2)pwd
说明pwd的功能:
_____________________________。
(3)cd/home
说明cd的功能:
_____________________________。
(4)date
说明date的功能:
_____________________________。
(5)Shell可以定义用户变量:
变量明=变量值。
而使用变量要在变量前加符号“$”。
例:
先定义exer变量的的值为/home/weixiang/,然后显示exer。
exer=/home/weixiang/
echo$exer
查看运行结果:
_____________________________。
(6)man命令,获得Linux命令的联机帮助信息。
格式:
man+命令名
使用此命令可获得系统中对指定命令的解释。
(7)who命令
who的功能:
_____________________________。
(8)read命令是从标准输入读入数据并将读入数据赋值给变量,调试以下程序,理解read的功能。
readvar1var2
1223
echo$var1$var2
(9)Ctrl+z命令
功能:
终止当前进程的执行。
(10)ps命令
功能:
查询正在执行的进程。
(11)wait命令
wait命令的功能是等待后台进程结束。
(12)sleep
该命令使进程暂停执行一段时间
(13)kill命令
kill命令的功能是终止一个进程的运行。
3、Linux环境下,掌握,编程->编译->执行,这三个程序的运行过程。
(1)调式:
打开Linux的应用程序—>附件—>文本编辑器,编写C语言程序,如下:
#include
#include
main()
{
printf("Helloworld!
\n");
}
保存,且扩展名是c,如保存为文件myfile.c,保存在root文件夹下。
说明:
C语言与Linux关系特别紧密,Linux核心程序的绝大多数都由C语言编写,C就是Linux的系统语言。
(2)编译:
编译命令是cc–o参数1参数2。
例1:
下面的命令是将程序myfile.c编译生成一个可执行文件exer。
cc–oexermyfile.c
(3)执行指令是运行可执行文件,对本题来说,可执行文件是exer
./exer
./表示当前目录,./exer表示运行当前目录下的可执行文件exer;运行文件也可以使用绝对路径。
4、编程
要求:
程序包含两个模块mianexer.c和subexer.c,现在用cc命令编译mainexer.c和subexer.c,并将编译后的目标模块直接连接成一个可执行程序exer。
注意:
mainexer.c和subexer.c这两个程序,必须其中一个是含有main主函数,而另一个程序是子函数,即被调用的函数,里面不能含有main主函数。
编译程序:
cc–oexermainexer.csubexer.c
执行程序:
./exer
试验二Linux进程系统调用——创建子进程
一.背景知识
在Linux系统中,用户应用程序通过进程系统调用可以创建进程、撤消进程等操作,达到控制进程的目的。
二.试验目的
1、使用系统调用函数fork()创建一个子进程。
2、理解父进程创建子进程后,多个进程在系统中并发执行的过程。
3、理解进程调度算法:
时间片轮转法。
三.实验原理或流程图
在Linux系统中进程0是系统引导时创建的,除此之外,系统中所有的进程均由系统调用fork创建。
fork系统调用用于创建一个新的子进程,该系统调用的格式为:
pid=fork()
其中pid是创建的子进程的标识符,是系统为子进程分配一个惟一的进程标识符pid,该进程标识符比系统最近一次分配的进程标识符大1;如果进程标识符已达到最大值,则从1开始查找原来已经分配,而进程已经结束的标识符。
父进程调用fork的返回值为子进程的标识符,如果创建子进程发生错误,则返回值为-1;子进程在父进程调用fork被创建之后,它的返回值为0。
所以如果pid>0,则程序进入父进程的执行环境里;如果pid==0,这程序进入子进程的执行环境里。
四.试验内容
1、创建子进程,掌握创建子进程函数fork()。
2、实现父进程和子进程的同步,掌握函数exit()和wait()。
五.试验步骤
1、调式以下程序,理解进程的家族关系
#include
main()
{
fork();
fork();
fork();
printf(“S”);
}
运行结果:
SSSSSSSS
分析:
创建进程系统调用fork(),在创建子进程时,子进程继承了父进程的进程表项,并将其父进程的上下文静态部分拷贝到子进程上下文中。
执行第一个fork调用时,进程A(即主进程main)创建了进程B;执行第二个fork调用时,进程A创建了进程C,进程B创建了进程D;执行第三个fork调用时,进程A创建了进程E,进程B创建了进程F,进程C创建了进程G,进程D创建了进程H。
因此,在UNIX系统中运行本程序,其进程家族树如下图所示。
2、进程的创建
#include
main()
{
intp1,p2;
while(p1=fork())==-1);/*创建进程p1,创建成功后退出*/
if(p1==0)/*CPU运行P1*/
putchar(‘b’);
else
{
while((p2=fork())==-1);
if(p2==0)
putchar(‘c’);
else
putchar(‘a’);
}
}
运行结果:
bca(有时会出现bac)。
分析:
从进程并发执行来看,输出bac,acb等情况都有可能。
原因:
fork()创建进程所需的时间要多于输出一个字符的时间,因此在主进程创建进程2的同时,进程1就输出了“b”,而进程1、进程2和主进程的执行次序及输出次序是随机的,所以会出现上述结果。
3、编程:
要求:
阅读上文,编写程序,功能是:
父进程利用fork创建子进程,创建成功后,父进程输出”Thisisparentprocess“和子进程的标识符,子进程输出”Thisisthechildprocess”和它得到的返回值。
4、exit系统调用。
一般用户进程在完成任务后应尽快结束。
在Linux系统中提供系统调用exit用于进程的自我结束。
格式为:
voidexit(status);
intstatus;
其中status是返回给结束进程的父进程的参数,为整数,一般为0。
wait系统调用。
系统调用wait是用来同步父进程与子进程的终止。
调用进程挂起自己等待其子进程暂停或终止发来软中断信号为止。
如果在wait调用之前子进程已经暂停或终止,则调用进程做完处理工作后便返回而不用等待。
格式为:
intwait(status)
intstatus
其中status是子进程的退出状态码。
函数返回子进程号。
调试以下程序理解上述两个函数的功能。
下面的程序的功能是父进程调用了fork创建了子进程,之后父进程进入等待状态,等到它的子进程结束返回后,它才能输入自己的信息并结束。
以下程序有2个地方程序出错,请找出来修改好。
#include
#include
#include
#include
intp1;
main()
{
while((pid=fork())==-1);
if(pid==0)
{
printf("thisthechildprocess.\n");
exit
(1);
}
else
{
wait(0);
printf("thechildprocesshasexited,theparentprocesswillexit.\n");
exit(0);
}
}
5、编程:
编写程序体现以下过程:
父进程要输出信息“Ianthefirstprocess.\n”并结束之前,必须等到它的孩子进程输出”Ianthesecondprocess.\n”并结束程序。
而子进程的结束又必须等到它的子进程输出”Ianthethirdprocess.\n”结束返回才能结束。
试验三Linux进程的无名管道通信
一.背景知识
父进程创建子进程,并通过管道进行通信。
二.试验目的
1、会使用系统调用函数fork()创建一个子进程。
2、理解父进程创建子进程后,多个进程在系统中并发执行的过程。
3、利用无名管道进行进程通信。
三.实验原理或流程图
无名管道为建立管道的进程及其子孙提供一条以比特流方式传送消息的通信管道。
利用Linux提供的系统调用pipe,可建立一条同步通信管道。
其格式为:
intfd[2];
pipe(fd);
发送进程利用文件系统的系统调用write(fd[1],buf,size),把buf中的长度为size字符的息送入管道入口fd[1],接收进程则使用系统调用read(fd[0],buf,size)从管道出口fd[0]读出size字符的消息置入buf中。
四.试验内容
1、理解有关无名管道的基础知识。
2、完成无名管道的创建。
3、在父进程和子进程之间利用无名管道进程数据传输。
五.试验步骤
1、理解有关无名管道的基础知识。
示例:
用C语言编写一个程序,建立一个pipe,同时父进程生成一个子进程,子进程向pipe中写入一字符串,父进程从pipe中读出该字符串。
#include
#include
main()
{
intx,fd[2];
charbuf[30],s[30];
pipe(fd);/*创建管道*/
while((x=fork())==-1);/*创建子进程失败时,循环*/
if(x==0)
{
sprintf(buf,"Thisisanexample\n");
write(fd[1],buf,30);/*把buf中字符写入管道*/
exit(0);
}
else/*父进程返回*/
{
wait(0);
read(fd[0],s,30);/*父进程读管道中字符*/
printf("%s",s);
}
}
2、编程:
父进程要输出信息并结束之前,必须等到它的孩子进程通过无名管道把信息传过来并结束进程后才能结束;而子进程的结束又必须等到它的子进程把数据“usepipetotransportdata;”通过无名管道传过来结束返回才能结束。
试验四区分fork(),exec()函数的使用
一.背景知识
理解进程的概念,以及父进程和子进程的关系。
理解fork()函数创建进程的含义。
二.试验目的
正确区分fork(),exec()函数在创建子进程的不同之处,加深对创建子进程的理解。
三.实验原理或流程图
在传统的Unix环境下,有两个基本的函数fork()、exec()用于创建和修改进程:
函数fork()用来创建一个新的进程,该进程几乎是当前进程(父进程)的一个完全拷贝;而函数族exec()用来启动另外的进程以取代当前运行的进程。
fork函数启动一个新的进程,前面我们说过,这个进程几乎是当前进程的一个拷贝:
子进程和父进程使用相同的代码段;子进程复制父进程的堆栈段和数据段。
这样,父进程的所有数据都可以留给子进程,但是,子进程一旦开始运行,虽然它继承了父进程的一切数据,但实际上数据却已经分开,相互之间不再有影响了,也就是说,它们之间不再共享任何数据了。
对于父进程,fork函数返回了子程序的进程号,而对于子程序,fork函数则返回零。
四.试验内容
1、阅读理解以下文字说明,理解fork()和exec()函数的区别。
2、调试程序并按要求完成程序的编写。
五.试验步骤
1、调试以下程序,这段程序演示了使用fork的基本框架:
#include
#include
main(){
inti;
if(fork()==0){
/*子进程程序*/
for(i=1;i<100;i++)printf("Thisischildprocess\n");
}
else{
/*父进程程序*/
for(i=1;i<100;i++)printf("Thisisparantprocess\n");
}
}
2、exec()函数族
下面我们来看看一个进程如何来启动另一个程序的执行。
在Linux中要使用exec函数族。
系统调用execve()对当前进程进行替换,替换者为一个指定的程序,其参数包括文件名(filename)、参数列表(argv)以及环境变量(envp)。
exec函数族当然不止一个,但它们大致相同,在Linux中,它们分别是:
execl,execlp,execle,execv,execve和execvp等。
请通过manexec命令来了解它们的具体情况。
一个进程一旦调用exec类函数,它本身就"死亡"了,系统把代码段替换成新的程序的代码,废弃原有的数据段和堆栈段,并为新程序分配新的数据段与堆栈段,唯一留下的,就是进程号,也就是说,对系统而言,还是同一个进程,不过已经是另一个程序了。
下面程序中hh是一个保存在root目录下的可执行文件,当前进程main在执行这个可执行文件后,它将被这个新执行的进程取代。
(注:
hh文件需要学生自己随意编写完成)
#include
main()
{
char*argv[]={"/root/hh",NULL};
execve("/root/hh",argv,NULL);
}
那么如果我的程序想启动另一程序的执行但自己仍想继续运行的话,怎么办呢?
那就是结合fork与exec的使用。
下面一段代码显示如何启动运行其它程序:
#include
#include
#include
charcommand[256];
main()
{
intrtn;/*子进程的返回数值*/
while
(1){
/*从终端读取要执行的命令*/
printf(">");
fgets(command,256,stdin);
command[strlen(command)-1]=0;
if(fork()==0){
/*子进程执行此命令*/
execlp(command,NULL);
/*如果exec函数返回,表明没有正常执行命令,打印错误信息*/
perror(command);
exit(errno);
}
else{
/*父进程,等待子进程结束,并打印子进程的返回值*/
wait(&rtn);
printf("childprocessreturn%d\n",rtn);
}
}
}
此程序从终端读入命令并执行之,执行完成后,父进程继续等待从终端读入命令。
试验五利用共享存储区机制实现生产者与消费者的进程同步关系
一.背景知识
使用共享变量的方式实现进程的同步关系。
二.试验目的
理解生产者和消费者的同步关系,通过对生产者消费者进程同步关系程序的编程,理解进程的同步关系。
三.实验原理或流程图
进程A使用kill(B,17),给进程号为B的进程发送信号17,该进程使用signal(17,stop)接收了信号17,并使用stop函数作出相应的处理。
进程A和进程B通过这两个函数实现相互通信,并达到进程的同步。
例如:
假如进程A是生产者,进程B是消费者,进程A生产一个产品后,就给进程B发送一个信号,如果进程B正在等待消费,这时候就不需要等待了,因为有产品了。
四.试验内容
1、利用共享变量的方式,实现生产者和消费者之间的进程同步。
2、调试程序并按要求完成程序的编写。
五.试验步骤
1、理解有关生产者与消费者进程同步的知识。
一个仓库可以存放K件物品。
生产者每生产一件产品,将产品放入仓库,仓库满了就停止生产。
消费者每次从仓库中去一件物品,然后进行消费,仓库空时就停止消费。
解答:
进程:
Producer-生产者进程,Consumer-消费者进程
共有的数据结构:
buffer:
array[0..k-1]ofinteger;
in,out:
0..k-1;
—in记录第一个空缓冲区,out记录第一个满的缓冲区
s1,s2,mutex:
semaphore;
s1控制缓冲区空;s2控制缓冲区满;mutex保护临界区。
初始化s1=k,s2=0,mutex=1
producer(生产者进程):
{Item_Typeitem;
while(true)
{
p(s1);
p(mutex);
produce(&item);
buffer[in]:
=item;
in:
=(in+1)modk;
v(mutex);
v(s2);
}
}
consumer(消费者进程):
{
Item_Typeitem;
while(true)
{
p(s2);
p(mutex);
item:
=buffer[out];
out:
=(out+1)modk;
v(mutex);
v(s1);
consume(&item);
}
}
2、调试以下程序理解理解它的功能。
生产者与消费者通过n(本题中n=10)个缓冲区进行数据的传输,生产者负责生产并把产品放入缓冲区,消费者负责从缓冲区里取出产品进行消费;对生产者来说,必须至少有一个空的缓冲区,才能生产产品,并把产品放入一个缓冲区,对消费者来说,必须至少有一个满的缓冲区,才能取出产品进行消费。
下面的程序的功能是父进程调用了fork创建了子进程,之后父进程作为生产者,子进程作为消费者,实现生产者消费者进程的同步关系。
#include
#include
#include
#include
#include
#include
//#include
#defineSHMKEY75
#defineK1024
intshmid;
intwait_marks;/*定义等待标志,如果为1,就等待;如果是0,就不再等待*/
inttimenum=0;/*定义输出的次数,如果已经输出了20次,程序就结束。
父进程和子进程共享*/
/*buffull=0定义满缓冲区个数变量,初始为0,父进程和子进程共享*/
/*bufempty=10定义空缓冲区个数变量,初始为10,父进程和子进程共享*/
voidwaiting(),stop();
main()
{
int*pbuffull,*pbufempty,*pint1;
char*addr;
externchar*shmat();
shmid=shmget(SHMKEY,K,0777|IPC_CREAT);
printf("shmid=%d\n",shmid);
addr=shmat(shmid,0,0);/*共享区首地址*/
pbuffull=(int*)addr;
pint1=(int*)addr;
pbuffull=pint1;
pint1++;
pbufempty=pint1;
*pbuffull=0;
*pbufempty=10;
intpid;
while((pid=fork())==-1);
if(pid>0)
{intproduct_num=1;/*定义生产了第几次了*/
externinttimenum;/*使用外部已经定义的变量,下同*/
while
(1)/*如果满足条件,生产者就不断的生产*/
{
if(timenum>=20)/*如果已经输出了20次,程序就退出并结束。
*/
exit(0);
if(*pbufempty<=0)
{
wait_marks=1;
signal(17,stop);
waiting();
}
else
{
(*pbufempty)--;
(*pbuffull)++;
printf("Thisisnumber%dproduct\n",product_num);
sleep
(1);
printf("thefullbufnumberis%d.\n",*pbuffull);
printf("theemptybufnumberis%d.\n",*pbufempty);
timenum++;product_num++;
/*生产一个产品之后,次数加1,生产的次数加1,满缓冲区加1,空缓冲区减1*/
kill(pid,17);
}
}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 操作系统 试验 手册 基于 Linux
![提示](https://static.bdocx.com/images/bang_tan.gif)