华中农业大学 学生实验报告
日期: 2019 年 11 月 28 日 成绩
课程名称 计算机操作系统 实验名称 进程控制与通信 实验类型 验证 设计
综合 创新
【实验目的】
实验目的:1、掌握进程的概念,明确进程和程序的区别。
2、认识和了解并发执行的实质。
3、分析进程争用资源的现象,学习解决进程互斥的方法。
实验要求:linux 环境下完成实验
【实验内容】
(一) 进程控制
(二) 进程间通信
(1) 信号量机制实验
(2) 进程的管道通信实验
(3) 消息的发送与接收实验
(4) 共享存储区通信
【实验环境】(含主要设计设备、器材、软件等)
Pc电脑一台
【实验步骤、过程】(含原理图、流程图、关键代码,或实验过程中的记录、数据等)
内容:
(一) 进程控制
1、进程的创建(必做题) 编写一段程序,使用系统调用 fork( )创建两个子进程,在系统中有一个父进程和两个子进程 活动。让每个进程在屏幕上显示一个字符;父进程显示字符“a”,子进程分别显示字符“b” 和“c”。 试观察记录屏幕上的显示结果,并分析原因。
原因是:在执行到fork()之前,只有一个进程在运行,执行到fork()后,父进程产生子进程,父进程的返回值大于0,子进程的返回值等于0,用于区分父子进程;之后父子进程并行执行并没有先后顺序之分(取决操作系统),所以使得运行结果不同。
2、 修改已编写的程序,将每个进程的输出由单个字符改为一句话,再观察程序执行时屏幕上出现 的现象,并分析其原因。(必做题)
原因跟上一道题目类似,父进程产生两个并行的子进程,两个子进程执行的顺序不能确定。
3、编写程序创建进程树如图 1 和图 2 所示,在每个进程中显示当前进程识别码和父进程识别码。(必 做题)
【思考题】
1、 系统是怎样创建进程的?
申请空白PCB
为新进程分配资源
初始化进程控制块(初始化标识信息,初始化处理机状态信息,初始化处理机控制信息)
将新进程插入就绪队列
2、 当首次调用新创建进程时,其入口在哪里?
进程的进程控制块(PCB)结构中的指向其TTS(任务状态段)的指针。
3、 当前运行的程序(主进程)的父进程是什么?
当前运行程序的父进程是应该是该进程的上一个进程
(二) 进程间通信
(1) 信号量机制实验
1.编写一段程序,使用系统调用 fork( )创建两个子进程,再用系统调用 signal( )让父进程捕捉 键盘上来的中断信号(即按 ctrl+c 键),当捕捉到中断信号后,父进程用系统调用 kill( )向两个 子进程发出信号,子进程捕捉到信号后,分别输出下列信息后终止:
Child process 1 is killed by parent!
Child process 2 is killed by parent!
父进程等待两个子进程终止后,输出以下信息后终止:
Parent process is killed!
结果:
实验要求:
(1)、运行程序并分析结果。
结果分析:在父进程产生两个进程之前,就对父进程进行signal设置,因为signal函数的意义就是如果产生了SIGINT信号,就会执行stop指令。于是结束了waiting()等待的指令产生了中断处理,而子进程同样也会相应产生中断。
(2)、如果把 signal(SIGINT,stop)放在①号和②号位置,结果会怎样并分析原因。
结果分析:根据signal的位置不同,发现结果完全不同,究其原因还是fork()函数会使得子进程集成父进程的所有信息包括软中断的信息,所以使得不同的位置控制不同的子进程。
(3)、该程序段前面部分用了两个 wait(0),为什么?
等待子进程运行结束。如果子进程没有完成,父进程一直等待。wait( )将调用进程挂起,直至 其子进程因暂停或终止而发来软中断信号为止。如果在 wait( )前已有子进程暂停或终止,则调用 进程做适当处理后便返回。
(4)、该程序段中每个进程退出时都用了语句 exit(0),为什么?
终止进程的执行。
2、修改上面的程序,增加语句 signal(SIGINT,SIG_IGN)和语句 signal(SIGQUIT,SIG_IGN),再观察 程序执行时屏幕上出现的现象,并分析其原因。
大体上的理解与上一题类似,但是注意后一句的signal 对之前设置的有覆盖作用。
3.编程用 fork()创建一个子进程代表售票员,司机在父进程中,再用系统调用 signal()让父进程 (司机)捕捉来自子进程(售票员)发出的中断信号,让子进程(售票员)捕捉来自(司机)发出 的中断信号,以实现进程间的同步运行
(2) 进程的管道通信实验
编制一段程序,实现进程的管道通信。使用 pipe()建立一条管道线。两个子进程 p1 和 p2 分别 向管道各写一句话:
Child 1 is sending message! Child 2 is sending message!
而父进程则从管道中读出来自于两个子进程的信息,显示在屏幕上。
分析结果:所谓管道,是指能够连接一个写进程和一个读进程的、并允许它们以生产者—消费者方式进行通信 的一个共享文件,又称为 pipe 文件。由写进程从管道的写入端(句柄 1)将数据写入管道,而读进 程则从管道的读出端(句柄 0)读出数据。所以两个子进程往fd[1]中写入内容,父进程从fd[0]中读取,所以才会有如上结果。
2.在父进程中用 pipe()建立一条管道线,往管道里写一句话,两个子进程接收这句话。
(3) 消息的发送与接收实验
1、 消息的创建、发送和接收。使用系统调用 msgget( ),msgsnd( ),msgrev( ),及 msgctl( )编制一 长度为1k 的消息发送和接收的程序。
程序说明:
① 为了便于操作和观察结果,编制二个程序 client.c 和 server.c,分别用于消息的发送与接收。
② server 建立一个 Key 为 75 的消息队列,等待其它进程发来的消息。当遇到类型为 1 的消息,则 作为 结束信号,取 消该队列 ,并退 出 server。server 每接收 到一个消 息后显示一句 “(server)received。”
③client 使用 key 为 75 的消息队列,先后发送类型从 10 到 1 的消息,然后退出。最后一个消息,即是 server 端需要的结束信号。
2、 在父进程中创建一个消息队列,用 fork 创建一个子进程,在子进程中将一条消息传送至消息队 列,父进程接受队列的消息,并将消息送屏幕显示。
对共享存储的理解首先要知道需要先在共享存储区内申请一块区域,用来接收要写的信息。
之后建立链接,把共享存储区的内容映射到虚空间内。shmget( ) 创建、获得一个共享存储区。shmat( ) 共享存储区的附接。从逻辑上将一个共享存储区附接到进程的虚拟地址空间上。shmdt( ) 把一个共享存储区从指定进程的虚地址空间断开。
3、 编程在主进程中创建两个子进程,在子进程 shmw()中创建一个系统 V 共享内存区,并在其中写 入格式化数据;在子进程 shmr()中访问同一个系统 V 共享内存区,读出其中的格式化数据。
【实验结果或总结】(对实验结果进行相应分析,或总结实验的心得体会,并提出实验的改进意见)
进程控制 总结: