在上一篇里,使用了读写文件的方式来实现进程间通信,使用了信号量完成了进程间的同步,虽然这种实现方式也能够完成任务,但是缺点就在于它需要读写磁盘。所以 linux 系统提供了多种多样的进程间通信的手段,帮助我们实现进程间通信。
不过,在讲解 Linux 进程间通信(后面简称 Linux IPC)之前,需要了解 Linux IPC的分类。
1. Linux IPC 分类
说分类不太准确,不过还是先按照此方式大概讲一下,方便初学者初步理解。linux ipc 大致可以分为下面四类:
- 最初的 Unix IPC:主要包括无名管道,有名管道,信号(上一个专题讲过)。
- System V IPC:主要包括 System V 共享内存、System V 消息队列、System V 信号量。
- 基于 socket IPC:主要使用套接字的方式进行通信。
- POSIX IPC:POSIX 共享内存、POSIX 消息队列、POSIX 信号量。
初学者可能有点懵圈,怎么有这么多,共享内存还分成 System V 和 POSIX 的?准确的说,Linux 是继承了先辈们的基因,它把 System V IPC 、POSIX 等等 IPC 的方式都实现了。这意味着,在实际编程的时候,你可以根据你自己的口味,选择一款你喜欢的方式。比如,System V 的共享内存和消息队列用起来比较方便,我就喜欢用它,而 System V 信号量用起来麻烦,我可以选择使用 POSIX 信号量,它的接口更加简单。
下面这张图说明了 Linux IPC 的历史(这才是准确的说法,说分类本身不恰当,但是学习的时候可以这样用):
linux下的进程通信手段基本上是从Unix平台上的进程通信手段继承而来的。而对Unix发展做出重大贡献的两大主力 AT&T 的贝尔实验室及 BSD(加州大学伯克利分校的伯克利软件发布中心)在进程间通信方面的侧重点有所不同。前者对Unix早期的进程间通信手段进行了系统的改进和扩充,形成了“System V IPC”,通信进程局限在单个计算机内;后者则跳过了该限制,形成了基于套接口(socket)的进程间通信机制。Linux则把两者继承了下来。
2. Linux IPC 常用手段
最后总结一下,Linux 实现 IPC 主要有以下几种方式:
- 无名管道(pipe)及有名管道(named pipe):无名管道只能用于有亲缘关系的进程,有名管道用于任意两进程间通信。
- 信号(signal):上一个专题讲的很详细了。
- 消息(message)队列:包括Posix消息队列system V消息队列。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。
- 共享内存(share memory):使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。
- 信号量(semaphore):主要作为进程间以及同一进程不同线程之间的同步手段。
- 套接口(Socket):更为一般的进程间通信机制,可用于不同机器之间的进程间通信。起初是由Unix系统的BSD分支开发出来的,但现在一般可以移植到其它类Unix系统上:Linux和System V的变种都支持套接字。
3. 总结
- 知道 Linux IPC 历史(或者说分类)
- 知道 Linux IPC 常用手段
参考资料:
[1] 深刻理解Linux进程间通信(IPC)