本篇博客更偏向于总括和导航,部分概念更细致的介绍将内嵌链接在文章中

重点内容

  • 初识进程间通信
  • 管道
  • 消息队列
  • 共享内存
  • 信号量

进程间通信的目的

  • 数据传输: 一个进程需要将它的数据发送给另一个进程
  • 资源共享: 多个进程之间共享同样的资源
  • 通知事件:一个进程需要向另一个或一组进程发送消息通知它(它们)发生了某种事件(如子进程终止时要通知父进程)
  • 进程控制: 有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变

进程间通信的主要方式

  • 管道
  • System V进程间通信
  • POSIX进程间通信

进程间通信的分类

管道

  • 匿名管道
  • 命名管道

System V IPC

  • System V 消息队列
  • SysTem V 共享内存
  • System V 信号量

POSIX IPC

  • 消息队列
  • 共享内存
  • 信号量
  • 互斥量
  • 条件变量
  • 读写锁

管道

怎么使用?戳我去管道博客🔗

首先,管道是Unix中最古老的进程间通信的形式。它用于进程间的单向通信

那么具体是怎样实现的呢?从标题里就可以发现,是基于文件

既然一个文件可以被多个进程打开,那么不妨将文件作为两个进程通信的媒介。但是一般位于磁盘上的文件,IO效率相比于CPU内存之类的读写速度慢了几个数量级,但文件是可以被加载到内存中的,而专门建立在内存中,而没有磁盘文件,专门用于进程间通信的内存级文件,我们就叫它管道文件

管道文件由内核维护


管道文件是单向的,可以是父进程->子进程,也可以子进程->父进程

原子性

头文件提供了宏PIPE_BUF,规定了保证原子性读写操作的最大字节数

  • 当要写入的数据量不大于PIPE_BUF时,linux将保证写入的原子性。
  • 当要写入的数据量大于PIPE_BUF时,linux将不再保证写入的原子性。

管道特点

  • 管道提供流式服务
  • 一般而言,进程退出,管道释放,所以管道的生命周期随进程
  • 一般而言,内核会对管道操作进行同步与互斥
  • 一个管道只有一个通信方向,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道

system V共享内存

共享内存区是最快的IPC形式。一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及
内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据,而是直接使用内存中的共享区。

读写共享区内存

挂接上的进程是真正意义上的看到同一块内存,而且完全可以像malloc申请出的一段内存一样操作,比如把共享区的内存当成字符串的缓冲区,直接把标准输入用fgets拷贝到共享内存中

不过默认的共享内存并没有同步互斥行为,需要额外控制,比如使用FIFO命名管道来完成同步操作

戳我去具体介绍🔗