进程间通信的各种方式及比较

进程间通信的各种方式

进程间通信的方法包括管道(PIPE)、消息队列、信号、共享内存以及套接字(Socket)。

一、管道

管道通常指无名管道,是UNIX系统IPC最古老的形式。

特点:

  1. 半双工(数据只能单向流动),具有固定的读端和写端
  2. 只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系
  3. 也可以看成是一种特殊的文件,对于它的读写也可以使用普通的read、write函数,但它不是普通的文件。

单个进程的管道几乎没有任何用处。所以,通常调用pipe的进程接着调用fork,这样就创建了父进程与子进程之间的IPC通道。

image-20190902113226353

如果数据从父进程流向子进程,则关闭父进程的读端(fd[0])与子进程的写端(fd[1]);反之,可以使数据流从子进程流向父进程。

二、FIFO 命名管道

FIFO,也称为命名管道,是一种文件类型。

特点:

  1. FIFO可以在无关的进程之间交换数据,与无名管道不同
  2. FIFO有路径名与之关联,以一种特殊设备文件形式存在于文件系统中。

FIFO的通信方式类似于在进程中使用文件来传输数据,只不过FIFO类型文件同时具有管道的特性。在数据读出时,FIFO同时清除数据,并且“先进先出”。

image-20190902113557256

三、消息队列

消息队列,是消息的链接表,存放在内核中。一个消息队列有一个标志符(即队列ID)来标识。

特点:

  1. 消息队列是面向记录的,其中的消息具有特定的格式以及特定的优先级
  2. 消息队列独立于发送与接收进程。进程终止时,消息队列及其内容并不会被删除。
  3. 消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取。

四、信号量

信号量是一个计数器,信号量用于实现进程间的同步与互斥,而不是存储进程间通信数据。

信号量可以用来控制多个进程对共享资源的访问。若此信号量的值为正,则进程可以使用该资源;进程将信号量减一,表示其使用了一个资源单元。若此信号量的值为0,则进程进入休眠状态,直至信号量位于0.若一个进程不再使用由一个信号量控制的共享资源时,该信号值增1.如果有进程正在休眠等待此信号量,则唤醒它们。

特点:

  1. 信号量用于进程间资源的同步,若要在进程间传递数据需要结合共享内存。
  2. 信号量基于操作系统的PV操作,程序对信号量的操作都是原子操作。
  3. 支持信号量组。

五、共享内存

共享内存,指两个或多个进程共享一个给定的存储区。

特点:

  1. 共享内存是最快的一种IPC,因为进程是直接对内存进行存取。
  2. 因为多个进程可以同时操作,所以需要同步
  3. 信号量+共享内存通常会结合在一起使用,使用信号量用来同步对同享内存的访问。

六、套接字

套接字也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同机器的进程通信。