Unix进程间通信之简介-总体概述和引子

0. 前言


进程间通信这块是学习linux-c编程的关键, 这篇为后续进程间通信技术的引子篇,后续讲到单独的某一个系统调用 都附该引用。

1. 概述


IPC是进程间通信(interprocess communication)的简称。系统上不同进程之间消息传递(message passing)的方式。
共享内存需要某种实行的
同步
(synchronization)参与运作。

发展阶段。

  • 管道(pipe) 是第一个广泛使用的IPC形式, 使用在Kernel之上的(应用程序或shell)。

    • 问题在于智能父子进程之间使用。
    • 解决方案是FIFO(无名管道)。
  • System V消息队列(System V message queue)

    • 用在同一主机上有亲缘关系或无亲缘关系的进程之间。
    • 大多数版本的Unix都支持。

    有亲缘关系不仅指父子,还包含子子关系,比如fork两次,派生2个子进程。
    所有Unix进程与init进程都有亲缘关系。

  • Posix消息队列

  • 远程过程调用(Remote Procedure Call, RPC)

    • 20世纪80年代中期,它是从一个系统(客户端主机)上某个程序调用另外一个系统(服务器主机)上某个函数的一种方法,是作为显式网络编程的一种替代方法开发的。

同步演变

  • 需要某种同步形式(往往是为了防止多个进程同时修改同一文件)的早期程序使用了文件系统的诡秘特性。
  • 记录上锁(record locking) 1988年由Posix.1标准化。
  • System V信号量(System V semaphore)是System V消息队列加上System V内核的同事伴随System V共享内存(System V shared memory)加入的。
  • Posix信号量(Posix semaphore)和Posix共享内存也由Posix实时标准加入。
  • 互斥锁(mutex)和条件变量(condition variable)是由Posix线程标准定义的两种同步形式。尽管往往用于线程间的同步,他们也能提供不同进程间的同步。
  • 读写锁(read-write lock)是另一种形式的同步。

2. 进程、线程与信息共享


在这里插入图片描述

按照传统的Unix编程模型,我们在一个系统上运行多个进程,每个进程都有各自的地址空间。Unix进程间的信息共享可以有多个方式:
1)左边的两个进程共享存留于文件系统中某个文件上的某些信息。为访问这些信息,每个进程都得穿越内核(例如read,write, lseek等)。当一个文件有待更新时,某种形式的同步是必要的,这样即可保护多个写入者,防止相互干扰,也可保护一个或多个读出者,防止写入者的干扰。
2)中间的两个进程共享驻留于内核中的某些信息。管道是这种共享类型的一个例子,System V消息队列和System V 信号量也是。现在访问共享信息的每次操作涉及对内核的一次系统调用。
3)右边的两个进程有一个双方都能访问的共享内存区。每个进程一旦设置好该共享内存区,就能根本不涉及内核而访问其中的数据。共享该内存区的进程需要某种形式的同步。
注意没有任何东西限制任何IPC技术只能使用两个进程。我们讲述的技术适用于任意数目的进程。

线程
虽然Unix系统中进程的概念已使用很久,一个给定进程中多个线程(thread)的概念却相对较新。Posix.1线程标准 (称Pthreads)是于1995年通过的。从IPC角度看来,一个给定进程内的所有线程共享同样的全局变量。
然而我们必须关注的是各个线程间对全局数据的同步访问。同步尽管不是一种明确的IPC形式,但它确实伴随许多形式的IPC使用, 以控制对某些共享数据的访问。

3. IPC对象的持续性


我们可以把任意类型的IPC的持续性(persistence)定义成该类型的一个对象一直存在多长时间。以下展示了三种类型的持续性。
在这里插入图片描述

  • 随进程持续的(process-persistent) , 例如管道和FIFO就是这种对象。
  • 随内核持续的(kernel-persisten) 例如System V的消息队列,信号量和共享内存区就是该类对象。Posix的消息队列,信号量和共享内存必须至少是随内核持续的,但也可以是随文件系统持续的,具体取决于实现。
  • 随文件系统持续的(filesystem-persistent)。 Posix消息队列,信号量和共享内存如果是使用映射文件实现的(不是必需条件),那么他们就是随文件系统持续的。
    在定义一个IPC对象的持续性时我们必须小心,因为它并不总是像看起来的那样。例如管道内的数据是在内核中维护的,但管道具备的是随进程的持续性而不是随内核的持续性:最后一个将某个管道打开着用于读的进程关闭该管道后,内核将丢弃所有的数据并删除该管道。类似的,尽管FIFO在文件系统中有名字,他们也只是具备随进程的持续性,因为最后一个将某个FIFI打开着的进程关闭该FIFI后,FIFI中的数据将被丢弃。
IPC类型 持续性
管道 随进程
FIFO 随进程
Posix互斥锁 随进程
Posix条件变量 随进程
Posix读写锁 随进程
fcntl记录锁 随进程
Posix消息队列 随内核
Posix有名信号量 随内核
Posix基于内存的信号量 随进程
Posix共享内存区 随内核
System V消息队列 随内核
System V信号量 随内核
System V共享内存区 随内核
TCP套接字 随进程
UDP套接字 随进程
Unix域套接字 随进程

注意该列表中没有任何类型的IPC具备随文件系统的持续性,但是我们说过有三种类型的Posix IPC可能会具备该持续性, 这取决于它们的实现。显然,向一个文件写入数据提供了随文件系统的持续性,但这通常不作为一种IPC形式使用。多数形式的IPC并没有在系统重新自举后继续存在的打算,因为进程不可能跨越重新自举继续存活。对于一种给定形式的IPC,要求它具备随文件系统的持续性可能会将其性能降低,而IPC的一个基本的设计目标是高新能。

4. 名字空间


  • 当两个或多个无亲缘关系的进程使用某种类型的IPC对象来彼此交换信息时,该IPC对象必须有一个某种形式的名字或标识符,这样其中一个进程(往往是服务器)可以创建该IPC对象,其余进程则可以指定同一个IPC对象。
  • 管道没有名字,因为不能用于无亲缘关系的进程间,但是FIFO有一个在文件系统中的Unix路径名作为其标识符(因此可用于无亲缘关系的进程间)。对于一种给定的IPC类型,其可能的名字的集合称为它的名字空间。名字空间非常重要,因为对于除普通管道以外的所有形式的IPC来说,名字是客户与服务器彼此连接以交换消息的手段。
IPC类型 用于打开或创建IPC的名字空间 IPC打开后的标识 Posix.1 1996 Unix98
管道 没有名字 描述符 * *
FIFO 路径名 描述符 * *
Posix互斥量 没有名字 pthread_mutex_t指针 * *
Posix条件变量 没有名字 pthread_cond_t指针 * *
Posix读写锁 没有名字 pthread_rwlock_t指针 *
fcntl记录上锁 路径名 描述符 * *
Posix消息队列 Posix IPC名字 mqd_t值 * *
Posix有名信号量 Posix IPC名字 sem_t指针 * *
Posix基于内存的信号量 没有名字 sem_t指针 * *
Posix共享内存区 Posix IPC名字 描述符 * *
System V消息队列 key_t键 System V IPC标识符 *
System V 信号量 key_t键 System V IPC标识符 *
System V共享内存区 key_t键 System V IPC标识符 *
路径名 描述符
Sun RPC 程序/版本 RPC句柄
TCP套接字 IP地址与端口 描述符 .1g *
UDP套接字 ip和端口 描述符 .1g *
Unix域套接字 路径名 描述符 .1g *

尽管Posix.1标准化了信号量,他们依然是可选的。

5. fork、exec和exit对IPC对象的影响


6. 出错处理: 包裹函数


7. Unix标准


8. 小结


相关推荐

  1. Linux进程通信消息队列

    2023-12-19 10:54:02       22 阅读

最近更新

  1. TCP协议是安全的吗?

    2023-12-19 10:54:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-19 10:54:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-19 10:54:02       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-19 10:54:02       20 阅读

热门阅读

  1. Arrays.asList()方法的大坑

    2023-12-19 10:54:02       30 阅读
  2. mybatis框架的orm机制(类和数据库表的映射)

    2023-12-19 10:54:02       38 阅读
  3. Unity3D UDP传输大文件怎么提高速度详解

    2023-12-19 10:54:02       48 阅读
  4. linux中数据库的概念、mysql的两种安装方法

    2023-12-19 10:54:02       34 阅读
  5. 笔记:LVM的简单使用

    2023-12-19 10:54:02       37 阅读
  6. npm的介绍和使用

    2023-12-19 10:54:02       21 阅读
  7. openssl数据压缩

    2023-12-19 10:54:02       37 阅读
  8. go语言实现文件夹上传前后端代码案例

    2023-12-19 10:54:02       38 阅读
  9. 获取 jira filter issue count 方法

    2023-12-19 10:54:02       44 阅读