一、什么是进程通信
二、为什么要OS的支持?
三、进程的通信方式
(一)共享存储
(二)消息传递
(三)管道通信
四、练习巩固
一、什么是进程通信?
在进程的执行过程中,不同的进程之间经常要合作,此时就必须要在不同的进程间进行一定的信息交流。进程通信是指两个进程间产生数据交互。同时,进程通信又必须有OS内核的支持。
二、为什么要OS的支持?
进程是分配系统资源的单位,各进程拥有的内存地址空间相互独立
如:
进程P、Q都可以访问它自己的空间,但不允许访问其他空间,如P访问Q空间不被允许。这么规定是出于安全的角度考虑,否则如果进程间能随意相互访问修改,则会有相当大的安全隐患。因此,两进程通信时不能直接到另一个进程空间中读取信息,此时就要通过第三章OS支持来完成通信。
通信的方式可大致分为以下三类:
三、进程的通信方式
(一)共享存储
实现过程:
可以向OS申请一片共享存储区,不同的进程可以在这片共享区读写数据,进而完成数据通信,如
P进程在共享区写入,Q进程在该区读出
另外,还要注意,若有多个进程都要往这个共享区写数据,则有可能导致写冲突,因此要保证各个进程对共享空间的访问应是互斥的,即当某一进程写这片区域时,其他进程不能访问。为实现互斥,各个进程可以使用操作系统内核提供的同步互斥工具(如P、V操作)来实现。
【补】通过“增加页表项/段表项”即可将同一片共享存储区映射到各个进程的地址空间中(内存管理中内容)
对于共享存储区,还可以把它分为两种:
(1)基于存储区的共享
OS在内存中划出一块共享存储区,数据的形式、存放位置都由通信进程控制,而非OS。这种方式速度快、灵活性高,是一种高级通信方式
(2)基于数据结构的共享
比如共享空间里只能放一个长度为10的数组,这种方式使进程只能控制所规定的数据结构来访问操作,速度慢、灵活性低,是一种低级通信方式
共享存储的简单理解就是,甲和乙中间有一个大布袋,甲和乙交换物品是通过大布袋进行的,甲把物品放在大布袋里,乙拿走。但乙不能直接到甲的手中拿东西,甲也不能直接到乙的手中拿东西。
(二)消息传递
在消息传递系统中,进程间的数据交换以格式化的消息为单位。若通信的进程之间不存在可直接访问的共享空间,则必须利用操作系统提供的消息传递方法实现进程通信。进程通过系统提供的发送消息和接收消息两个原语进行数据交换。这种方式隐藏了通信实现细节,使通信过程对用户透明,简化了通信程序的设计,是当前应用最广泛的进程间通信机制。在微内核操作系统中,微内核与服务器之间的通信就采用了消息传递机制。由于该机制能很好地支持多处理机系统、分布式系统和计算机网络,因此也成为这些领域最主要的通信工具。
【补充解释】
1.格式化的消息由两个部分组成:消息头,消息体:
2.原语是一种特殊的程序,具有原子性,即这段程序的运行必须一气呵成,不可中断
消息传递有两种方式:
(1)直接通信方式
消息发送进程要指明接收进程ID
过程:(设P发信息给Q)
操作系统管理着各个进程的PCB(在OS内核空间中),当然也包括Q进程的PCB,在其中有进程Q的消息队列,发送给Q、Q需要接收的消息都接在其消息队列中。进程P要发信息给Q,①先在P自己的空间里完善消息(msg);②然后P使用OS提供的发送原语sent(Q,msg)(指明了要将msg发给Q),导致内核空间接收了msg,③并将其挂在Q的信息队列中;之后,④Q使用接收原语receive(p,&msg)(指明了要接受P发来的msg),然后OS检查Q的消息队列找到msg,再将其复制到Q的空间中,完成通信。
由此可见,直接通信方式要“指名道姓”地传递。
(2)间接通信方式
以“信箱”作为中间实体进行消息传递
过程:(设P发信息给Q)
①P通过系统调用申请一个(或多个)“信箱”(A)
②P在自己的空间中完善消息msg
③P用发送原语sent(A,msg)(指明往A信箱发msg,没有指明发给哪个进程)
④Q用接收原语receive(A,&msg)(从A信箱接收msg)
⑤OS将msg复制到Q空间
【注】可以多个进程往同一个信箱sent消息,也可以多个进程从同一个信箱中receive消息
(三)管道通信
如图,某一时刻只能单向流动(左—>右/右—>左)不能双向同时进行
其中,“管道”是一个特殊的共享文件(pipe文件),其实就是在内存中开辟一个大小固定的内存缓冲区
过程:
先向OS申请一个管道,然后再通过管道传递信息,数据在管道中是先进先出的
对比共享存储方式:
共享存储在共享区中,进程对数据的存放位置、数据形式没有什么限制,而管道通信在进程读写时要遵循先进先出的规则
【注】
1.单个管道只能使用半双工通信,若要实现双向同时通信,则要设置两个管道,如:
2.各个进程要互斥地访问管道(由OS实现)
3.只要管道非空,读进程就能从管道中读出数据,若数据被读空,则读进程阻塞,直到写进程往管道中写入新的数据,再将读进程唤醒。只要管道不满,写进程就能往管道中写入数据,若管道写满,则写进程阻塞,直到读进程读出数据,再将写进程唤醒。
4.管道中的数据一旦被读出,就彻底消失。因此,当多个进程读同一个管道时,可能会错乱。对此,通常有两种解决方案:①一个管道允许多个写进程,一个读进程(参考408真题)(多个写进程轮流向管道里写)﹔②允许有多个写进程,多个读进程,但系统会让各个读进程轮流从管道中读数据(Linux的方案)。
四、练习巩固
1.用信箱实现进程间互通信息的通信机制要有两个通信原语,它们是()。
A.发送原语和执行原语 B.就绪原语和执行原语
C.发送原语和接收原语 D.就绪原语和接收原语
2.两个合作进程无法利用()交换数据。
A.文件系统 B.共享内存
C.高级语言程序设计中的全局变量 D.消息传递系统
3.【2014统考真题】下列关于管道(Pipe)通信的叙述中,正确的是()
A.一个管道可实现双向数据传输 B.管道的容量仅受磁盘容量大小限制
C.进程对管道进行读操作和写操作都可能被阻塞 D.一个管道只能有一个读进程或一个写进程对其操作
答案:
1.C
用信箱实现进程间互通信自的通信机制要有两个通信原语,它们是发送原语和接收原语,故选C。
2.C
不同的进程拥有不同的代码段和数据段,全局变量是对同一进程而言的,在不同的进程中是不同的变量,没有任何联系,所以不能用于交换数据。此题也可用排除法做,选项A、B、D均是课本上所讲的。管道是一种文件。
3.C
管道是一种固定大小的缓冲区,管道的大小通常为内存的一页,其大小并不是受磁盘容量大小的限制,选项B错误。一个普通管道只允许单向通信,若要实现父子进程双向通信,则需要定义两个管道,而每个管道向不同方向发送数据,选项A错误。当管道满时,写进程在写管道会被阻塞,而当管道空时,读进程在读管道会被阻塞,选项C正确。父进程创建一个管道后,由于管道是一种特殊的文件,因此所有子进程也继承了父进程的管道,并使用它来与父进程进行通信,选项D错误。