首先看一下进程间通信的概念(IPC:InterProcess Communication):每个进程各有不同的用户地址空间,如何一个进程的全局变量是不能被别的进程看见的,所以进程间通信都要经过内核,在内核中开辟一个缓存区,这个缓存区是所有与缓存区相关的进程都能访问的。进程1把数据从用户空间拷到内核缓存区,进程2再从缓存区把数据读到自己的用户空间。内核提供的这种机制就叫做进程间通信。


wKiom1cJzRyyl5RBAAA7kjwiSGM608.png

所以这8中通信方式就是在内核开辟缓存区的8种不同方式。

注意:每个IPC都会维护一个结构体(ipc_perm):


wKioL1cJ0vqitKUpAAA4OOhtTXs969.png

一.匿名管道(pipe):

匿名管道是一种半双工(在同一信道上,同一时刻只能接受或者发送数据)的通信方式,数据只能单向流动。匿名管道通过文件描述符进行操作,子进程会继承父进程的文件描述符。所以匿名管道只能用于有血缘关系的进程的进程间通信。

创建匿名管道的过程:

  1. 父进程通过pipe函数创建一个管道,得到两个文件描述符指向管道的两端。

  2. 父进程调用fork函数创建一个子进程,子进程会继承父进程PCB中的一部分数据,所以子进程也有两个文件描述符指向管道的两端。

  3. 父进程关闭管道读端,子进程关闭管道写端(close函数关闭读/写端)。注:应该先写入数据再进行读操作(问题:难道不能父进程关闭写端,子进程关闭读端?)

注:管道是以环形队列实现的,是以流的形式传递数据的。


二.命名管道(named pipe或FIFO):

命名管道也是一种半双工的通信方式,但它是通过路径名与缓存区关联。因为路径名在系统中是全局的,所以不同的进程即使没有血缘关系也能进行通信。

创建命名管道的方式:

  1. 在Shell下交互的建立一个命名管道。(manode或mkfifo)

  2. 在程序中使用系统调用函数建立命名管道。


三.高级管道(popen):(等待更新)

将另一个程序当作一个新的进程在当前程序进程中启动,它相当于当前程序的子进程。


四.消息队列(message queue):

消息队列是消息的链表,存放在内核中并由消息队列标识符标识,提供了一种从一个进程向另一个进程发送数据块(有不同的类型值)的方法,它可以设置为全双工的通信方式。

消息队列结构体:

wKiom1cKDSPxtvn7AABs33uSO4Y754.png

注:重要的是前三个和最后两个。

五.信号量(semophore):信号量的本质是一种数据操作锁,它本身不具有数据交换的功能,而是通过控制其他通信资源的P/V来实现进程间的通信,它也可以设置为全双工的通信。


六.信号(sinal):信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。(待更新)


七.共享内存(shared memory):共享内存就是一个进程映射出一段可以被别的进程所访问的内存,这段内存由一个进程所创建,但能被其它进程访问。共享内存是IPC中最快的一种通信方式,是针对其它进程间通信方式效率低而设计,通常是和其它通信方式配合使用。(待更新)


八.套接字:套接字是一种特殊的通信方式,它可以用在不同机器之间的通信。(待更新)