进程之间的通信方式

【参考文章】:进程间的通信方式——pipe(管道)

【参考文章】:进程间通信IPC (InterProcess Communication)

1. 定义

  每个进程各自有不同的用户地址空间,任何一个进程的变量在另一个进程中都看不到。所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程A把数据从用户空间拷到内核缓冲区,进程B再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信。

  本质:进程之间可以看到一份公共资源,根据提供这份资源的形式或者提供者不同,造成了通信方式不同。

2. 通信方式

2.1 管道(pipe)

2.1.1 工作原理

  1. 父进程创建管道,得到两个⽂件描述符指向管道的两端;

  2. 父进程fork出子进程,⼦进程也有两个⽂件描述符指向同⼀管道;

  3. ⽗进程可以往管道⾥写,⼦进程可以从管道⾥读,管道是⽤环形队列实现的,数据从写端流⼊从读端流出,这样就实现了进程间通信。 

  4. 管道只支持单向通信

 

2.1.2 缺点

  1. 半双工的通信,数据只能单向流动;

  2. 只能在具有亲缘关系的进程间使用,进程的亲缘关系通常是指父子进程关系;

2.1.3 高级管道

  1. 流管道 s_pipe:可以实现全双工通信,可以双向传输;

  2. 有名管道 name_pipe:有名管道不同于匿名管道之处在于它提供了一个路径名与之关联,以有名管道的文件形式存在于文件系统中,这样,即使与有名管道的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过有名管道相互通信,因此,通过有名管道不相关的进程也能交换数据。值的注意的是,有名管道严格遵循先进先出(first in first out),对匿名管道及有名管道的读总是从开始处返回数据,对它们的写则把数据添加到末尾。它们不支持诸如lseek()等文件定位操作。有名管道的名字存在于文件系统中,内容存放在内存中。

2.2 信号量(semophore)

  信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。

2.3 信号(signal)

  1. 信号是Linux系统中用于进程间互相通信或者操作的一种机制,信号可以在任何时候发给某一进程,而无需知道该进程的状态。

  2. 如果该进程当前并未处于执行状态,则该信号就由内核保存起来,直到该进程恢复执行并传递给它为止。

  3. 如果一个信号被进程设置为阻塞,则该信号的传递被延迟,直到其阻塞被取消是才被传递给进程。

2.4 消息队列(mesage queue)

2.4.1 定义

  消息队列是存放在内核中的消息链表,每个消息队列由消息队列标识符标识。

2.4.2 特点 

  1. 消息队列是消息的链表,具有特定的格式,存放在内存中并由消息队列标识符标识;

  2. 消息队列允许一个或多个进程向它写入与读取消息;

  3. 管道和消息队列的通信数据都是先进先出的原则;

  4. 消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取.比FIFO更有优势;

  5. 消息队列克服了信号承载信息量少,管道只能承载无格式字 节流以及缓冲区大小受限等缺;

  6. 目前主要有两种类型的消息队列:POSIX消息队列以及System V消息队列,系统V消息队列目前被大量使用。系统V消息队列是随内核持续的,只有在内核重起或者人工删除时,该消息队列才会被删除;

2.5 共享内存

  共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号量,配合使用,来实现进程间的同步和通信。

2.6 套接字(socket)

  套接字是一种通信机制,凭借这种机制,客户/服务器(即要进行通信的进程)系统的开发工作既可以在本地单机上进行,也可以跨网络进行。也就是说它可以让不在同一台计算机但通过网络连接计算机上的进程进行通信。

原文地址:https://www.cnblogs.com/virgosnail/p/12483202.html