进程、线程一类的,其实接触得挺早,但是没有深入使用。最早认识多进程多线程,是在学校网络中心参加一个并行计算比赛时了解的。但是建立的认识就是MPI、OPENMP之类的。然后没了解多久,就开始了GPU和PHI的调用了。

真要自己说清楚进程线程的区别,还真是比较难。一方面很早接触就往应用上走,没有深入了解实现原理;另一方面轮子封装得实在是好,一些坑早就被趟平了,也就没机会接触到。

然而这又是了解当今多核计算必不可缺的一环,短板还是得补上。

以前对进程通信方式的理解,就是两种,共享内存与消息同步。共享内存相当于定义共同访问空间;消息同步相当于发布者订阅者一类的方式。

不过这个理解还是比较狭隘的,或者还是十分简陋的。针对上述的理解,现在的我会质疑,共享内存怎么在进程间实现?那管道一类的方式又是属于哪种通信类型?事实上还不能简单以两种方式总结进程通信方式。

结合网上的资料以及手中的UNIX环境高级编程(APUE),以下是本人对进程通信的新的理解。

进程通信方式

  1. 管道(pipe)
  2. 命名管道(FIFO)
  3. 信号(signal)
  4. 消息队列
  5. 共享内存
  6. 信号量
  7. 套接字(socket)

IPC方式详解

InterProcess Communication -> IPC

管道

  1. 在APUE中的描述:管道是UNIX系统IPC的最古老的方式,所有UNIX都支持。

  2. 特征

    • 历史上,曾经是半双工的,也即数据只能往一个方向流动;
    • 管道智能在具有公共祖先的两个进程之间使用;
  3. 示例

    • 下图来自APUE:
    • 截图展示了管道使用的方式:
      • 通常,一个管道由一个进程创建,在进程调用fork之后,这个管道就能在父进程和子进程之间使用了。
      • 这里同时还提到一个概念:协同进程,当一个过滤程序既产生某个过滤程序的输入,又读取改过滤程序的输出时,它就变成了协同进程(coprocess)。
  4. 理解

  • 管道为什么不能在非公共祖先的进程之间使用?由于管道没有名字的原因,所以不能跨进程的地址空间进行使用。这里这句话不是绝对的,因为从技术上可以在进程间传递管道的描述符。
  • 那在命令行中常用的管道(命令)|又是什么意思?实际上是每个单独的程序(进程)与内核产生的管道(通过标准输入0和标准输出1)实现通信,然后内核把上一条命令的标准输出与下一条命令的标准输入关联。而并非两个进程直接相关的管道。

命名管道

  1. 区别于管道,命名管道支持不相关进程的通信。

  2. FIFO实际是一种文件类型。FIFO的路径名存在于文件系统中。

  3. 用途

    • shell命令使用FIFO将数据从一条管道传送到另一条时,无需创建中间临时文件;
    • 客户进程-服务器进程应用程序中,FIFO用作汇聚点,在客户进程和服务器进程二者之间传递数据;
  4. 理解

  • 如何实现命名管道?从其名字看,关键就在于命名,并把命名共享到需要通信的两者或多者之间。而同时注意到FIFO是一种文件类型,所以其也有绝对路径相对路径的说法。本人姑且粗鄙地理解成通过一个txt文件传递信息,但是不需要真正写到txt文件上都可以进行通信。

* XSI IPC

  1. 其包括消息队列信号量以及共享存储器

  2. 此类的IPC都用一个非负整数的标识符加以引用

    • 标识符是IPC对象的内部名:当一个IPC结构被创建,然后又被删除时,与这种结构相关的标识符连续加1,直到达到一个整型数的最大正值,然后又回转到0;
    • 为使多个合作进程能够在同一IPC对象上汇聚,需要提供一个外部命名方案:每个IPC对象斗鱼一个键关联,将这个键作为该对象的外部名。方式如下:
      • 存储标识符在某处(如一个文件)以便客户进程取用
      • 在一个公用头文件中定义一个客户进程和服务器进程都认可的键
      • 调用ftok把得到认同的一个路径名和项目ID转换成一个键
  3. 理解

  • 有点像命名管道嘛。。就是提供不一样的数据结构。
  • XSI IPC的一个基本问题是,在系统范围内起作用的,没有引用计数。
  • XSI IPC的另一个问题是,在文件系统中没有名字。
消息队列
  1. 消息队列是消息的链接表,存储在内核中,由消息队列标识符标识
信号量
  1. 信号量是一个计数器,用于为多个进程提供对共享数据对象的访问

  2. 为了正确的实现信号量,信号量的测试以及减1操作应当是原子操作,为此信号量通常是在内核中实现的

共享存储器
  1. 共享存储允许两个或多个进程共享一个给定的存储区

  2. 最快的IPC,无需在客户进程和服务器进程之间复制

  3. 唯一窍门,在多个进程之间同步访问一个给定的存储区

    • 信号量
    • 互斥量

参考内容

  1. Linux进程间通信的几种方式总结–linux内核剖析(七)

本文作者:Tobin
本文地址http://www.thirteenyu.com/2018/04/11/tech-apue-process-communcation/
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!