欢迎光临
我们一直在努力

一网打尽Linux IPC(一):进程间通信完全指南——总体介绍

示例代码

  • github: https://github.com/lengjingzju/notes/tree/master/code/linux_ipc
  • gitee: https://gitee.com/lengjingzju/notes/tree/master/code/linux_ipc

一、Linux IPC 概述

在 Linux 系统中,进程间通信(IPC,Inter-Process Communication) 是指在不同进程之间传递数据或信号的机制。由于每个进程拥有独立的虚拟地址空间,一个进程无法直接访问另一个进程的数据,因此需要借助操作系统提供的 IPC 工具来实现进程间的协作与同步。

IPC 不仅是操作系统课程的核心内容,更是实际开发中构建高性能、可扩展系统的基础技能。无论是构建多进程服务器、实现进程间任务协同,还是进行资源同步与数据共享,掌握 IPC 都是 Linux 后端开发工程师的必备能力。

二、IPC 工具分类

根据功能和用途,Linux IPC 工具可分为以下几类:

1. 通信工具

用于在进程之间传递数据。

数据传输
  • 字节流:数据以无边界字节流形式传输
    • PIPE(无名管道)
    • FIFO(命名管道)
    • TCP 套接字
  • 消息:数据以有边界消息形式传输
    • SYSV 消息队列
    • POSIX 消息队列
    • UDP 套接字
  • 伪终端:模拟终端设备,用于进程间通信
共享内存

将一块内存区域映射到多个进程的地址空间,进程可直接读写该区域。

  • SYSV 共享内存
  • POSIX 共享内存
  • 文件内存映射
  • 匿名内存映射

2. 同步工具

用于协调进程或线程的执行顺序,防止竞争条件。

线程同步(同一进程内)
  • mutex(互斥量)
  • rwlock(读写锁)
  • cond(条件变量)
  • spin(自旋锁)
  • barrier(屏障)
进程同步
  • 文件锁
    • 记录锁(fcntl)
    • 文件锁(flock)
  • 信号量
    • SYSV 信号量
    • POSIX 命名信号量
    • POSIX 无名信号量
  • 信号:常称为软中断,有中断号,用于通知进程事件发生

三、IPC 工具属性对比

下表总结了常用 IPC 工具的关键特性:

工具类型名字空间对象描述符可访问性持久性
PIPE无名管道 无名 文件描述符 相关进程 进程
FIFO命名管道 文件路径名 文件描述符 权限掩码 进程
SYSV消息队列 IPC键key_t IPC标识符int 权限掩码 内核
SYSV信号量 IPC键key_t IPC标识符int 权限掩码 内核
SYSV共享内存 IPC键key_t IPC标识符int 权限掩码 内核
POSIX消息队列 IPC路径名 mqd_t描述符 权限掩码 内核
POSIX命名信号量 IPC路径名 sem_t*指针 权限掩码 内核
POSIX共享内存 IPC路径名 文件描述符 权限掩码 内核
文件内存映射 路径名 文件描述符 权限掩码 文件
匿名内存映射 无名 相关进程 进程
flock()文件锁 文件路径名 文件描述符 open()操作 进程
fcntl()文件锁 文件路径名 文件描述符 open()操作 进程
TCP套接字 IP+端口 文件描述符 任意进程 进程
UDP套接字 IP+端口 文件描述符 任意进程 进程
Unix域套接字 路径名 文件描述符 权限掩码 进程
POSIX无名信号量 无名 sem_t*指针 内存权限 进程
POSIX互斥锁 无名 pthread_mutex_t* 同一进程 进程
POSIX读写锁 无名 pthread_rwlock_t* 同一进程 进程
POSIX条件变量 无名 pthread_cond_t* 同一进程 进程

关键术语解释

  • 相关进程:同一进程通过 fork() 创建的进程(父子进程或兄弟进程)
  • 权限掩码:通过文件系统权限控制访问
  • 持久性:
    • 进程持久性:IPC 对象持续到最后一个使用它的进程关闭或关闭该对象为止
      • 注:FIFO特殊,所有进程关闭了FIFO,但文件系统的FIFO节点一直保持着,需要unlink()显式删除
    • 内核持久性:IPC 对象持续到内核重启或显式删除为止
    • 文件系统持久性:IPC 对象持续到显式删除,内核重启不影响
  • POSIX的IPC路径名以 / 开头,且后面的路径不含 /

四、数据传输与共享内存机制

数据传输机制

  • 写入过程:数据从进程缓冲区复制到内核缓冲区
  • 读取过程:数据从内核缓冲区复制到进程缓冲区
  • 特性:
    • 读取操作是破坏性的,数据被消耗后其他进程无法再次读取
    • 默认情况下,空读/满写会阻塞进程
    • 字节流无边界,可读取任意字节
    • 消息有边界,一次读取一条完整消息
  • 共享内存机制

  • 直接内存访问:进程通过映射的虚拟地址直接读写共享内存
  • 同步需求:需要额外同步机制(如信号量)保护共享数据
  • 性能优势:避免了数据在内核和用户空间之间的复制,是最高效的 IPC 方式
  • 内存映射类型:
    • 文件映射:基于文件内容初始化内存
    • 匿名映射:分配新内存区域
  • 五、IPC 选择策略

    选择依据

  • 通信模式

    • 一对一 vs 一对多 vs 多对多
    • 单向 vs 双向
  • 性能要求

    • 共享内存 > 消息队列 > 管道 > 套接字(本地通信)
  • 平台兼容性

    • POSIX IPC 标准化程度高,可移植性好
    • System V IPC 历史悠久,广泛支持
  • 开发复杂度

    • 管道和 FIFO 简单易用
    • 共享内存需要额外同步机制
  • 持久性需求

    • 是否需要跨进程生命周期的持久存储
  • 典型应用场景

    • 父子进程通信:PIPE
    • 任意进程通信:FIFO、消息队列、共享内存
    • 高性能数据共享:共享内存 + 信号量
    • 网络通信:套接字
    • 线程同步:互斥锁、条件变量
    • 进程同步:信号量、文件锁

    六、示例代码概览

    在本次系列文章中,我们将以统一的示例模式演示各种 IPC 机制:父进程(或主线程)从终端读取数据,通过 IPC 机制传递给子进程(或子线程),子进程将数据输出到终端。输入 “q” 退出程序。

    示例程序包括:

    • test_pipe.c – PIPE(无名管道)示例
    • test_fifo.c – FIFO(命名管道)示例
    • test_sysv_msg.c – SYSV 消息队列示例
    • test_sysv_shm.c – SYSV 共享内存示例
    • test_posix_mq.c – POSIX 消息队列示例
    • test_posix_shm.c – POSIX 共享内存示例
    • test_thread_cond.c – 线程条件变量示例
    • test_thread_sem.c – 线程信号量示例
    • test_signal_sender.c / test_signal_reciver.c – 信号通信示例

    七、系列文章安排

    本系列将分六篇文章深入讲解 Linux IPC:

  • 总体介绍(本文):全面概述 Linux IPC 机制
  • PIPE、FIFO 与信号:讲解最简单的进程间通信方式
  • System V IPC:深入探讨消息队列、信号量和共享内存
  • POSIX IPC:介绍现代、可移植的 IPC 机制
  • 线程同步机制:讲解同一进程内的线程同步工具
  • 结语与实战指南:回顾IPC,总结与展望
  • 八、总结

    Linux IPC 提供了丰富多样的进程间通信与同步机制,每种机制都有其适用场景和优缺点。选择合适的 IPC 机制需要综合考虑通信模式、性能需求、平台兼容性和开发复杂度等因素。

    掌握 IPC 不仅是理解操作系统原理的关键,更是构建高性能、可靠分布式系统的基础。通过本系列文章,我们将从理论到实践,全面掌握 Linux IPC 的方方面面,为开发高效的多进程/多线程应用打下坚实基础。

    在接下来的文章中,我们将从最简单的 PIPE 和 FIFO 开始,逐步深入各种 IPC 机制的内部原理和实际应用,敬请期待!


    下一篇预告:我们将深入讲解 PIPE(无名管道)和 FIFO(命名管道),这是 Linux 中最基本、最常用的进程间通信方式,通过实际代码示例展示其工作原理和使用方法。

    赞(0)
    未经允许不得转载:171主机测评 » 一网打尽Linux IPC(一):进程间通信完全指南——总体介绍
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址