内容正文:
操作系统原理(第2版)
3.7.1 进程通信的概念
进程的特征之一是进程的独立性。一个进程不能访问另一个进程的数据或代码,以保证进程之间不会相互干扰,但由此也造成了进程之间无法直接交换数据,而需要借助进程通信机制来实现。可以采用如下图所示的两种方案来实现在进程之间传递数据。
3.7 进程通信
进程通信方案:
(1)发送、接收双方经过事先约定,利用磁盘等外存设备由发送进程A把要交换的数据写入外存的指定区域,接收进程B从该区域读取数据。这种方案实现简单,只需要操作系统的文件系统即可,但通信过程却需要I/O操作。
(2)利用内核运行在核心态的特点,发送进程A通过内核程序将数据写入内核空间指定的区域,接收进程B则通过另一组内核程序从内核指定区域中读取数据,并写入接收进程B的内存数据空间,从而实现数据从进程A传送到进程B。这种方案需要操作系统专门的系统调用来实现,数据传送不需要I/O操作(全部在内存中完成),速度快。
3.7 进程通信
进程通信分为如下两种:
(1)低级通信。进程之间一次只能传送很少的信息。低级通信的优点是速度快;缺点是传递的信息量少、效率低,通信过程对用户不透明,因此编程较复杂。低级通信主要是作为互斥与同步的工具来使用,所以我们也将P、V原语称为低级通信原语。
(2)高级通信。进程间一次可以传送大量的信息。优点是通信效率高,通信过程对用户透明,编程相对较简单。高级通信的目的不仅是为了控制进程的执行速度,而且是为了交换大量的信息。
3.7 进程通信
进程之间的高级通信分为如下3种:
① 共享内存通信方式。通信双方利用共享的内存区来实现进程间
通信。
② 共享文件通信方式。通信双方利用共享一个文件来实现进程间
通信。该通信方式又称为管道通信,而被共享的文件称为管道。
③ 消息传递通信方式。利用操作系统提供的消息传递系统来实现
进程间通信,进程间以消息为单位来进行信息交换。
3.7 进程通信
3.7.2 共享内存通信方式
方法:在内存中划出一块内存区作为共享数据区,称为共享内存分区,要通信的进程双方将自己的虚拟地址空间映射到共享内存分区上(如下图)。
通信时,发送进程将需要交换的信息写入该共享内存分区中,接收进程从该共享内存分区中读取信息,从而实现进程之间的通信。
特点:是进程之间最快捷、最有效的一种通信方式。UNIX、Windows、OS/2等操作系统都采用了这种通信方式。
3.7 进程通信
3.7.3 消息缓冲通信方式--属于直接通信方式
若采用消息缓冲通信方式,则发送进程利用发送命令(原语)直接将信息发送到接收进程的消息队列,而接收进程则利用接收命令(原语)从自己的消息队列中取出消息。进程间信息交换以消息为单位。
对于发送者,在通信中存在两种可能的行为:① 发送完消息后不等消息被接收者接收就继续前进;② 发送完消息后阻塞自己直到收到接收者的回答消息后才继续前进。
对于接收者,也存在两种可能的行为:① 若有消息则接收这个消息后继续前进,若无消息则必须等待消息的到来(即阻塞自己);② 若有消息则接收这个消息后继续前进,若无消息则放弃接收消息而继续前进。
进程之间的通信分为单向通信和双向通信。
3.7 进程通信
消息缓冲机制通信过程描述如下:
(1)发送者在发送消息前,先在自己的内存空间设置一个发送区,把欲发送的消息填入其中。
(2)发送者申请一个消息缓冲区,将已准备好的消息从发送区送到该消息缓冲区,并将发送者进程的名字、消息的开始地址以及消息的长度(通常以字节或字为单位)等信息填入该消息缓冲区中,然后把该消息缓冲区挂到接收进程的消息链上。
(3)接收者在接收消息前先在自己的内存空间设置相应的接收区。
(4)接收者摘下消息链上的第一条消息,将该消息从消息缓冲区复制到接收区,然后释放该消息缓冲区。
3.7 进程通信
消息缓冲区数据结构描述如下:
struct messagebuffer
{ int sender; //发送进程标识符
int size; //消息长度
char text[MAXSIZE]; //消息正文,MAXSIZE为数组text的长度
struct messagebuffer *next;
// next为指向下一个消息缓冲区的指针
}
3.7 进程通信
发送原语send描述如下:
void send(receiver,a)
{
lock out interrupts; //关中断