进程间通信有三种核心机制:管道适用于亲缘进程的单向轻量通信,消息队列支持异步结构化可靠传递,共享内存实现高频低延迟数据共享,需依场景选择。
进程间通信(IPC)的核心目标很明确:让彼此隔离的进程安全、高效地交换数据。管道、消息队列和共享内存是三种最常用且定位清晰的机制,选对场景比记住API更重要。
管道适合简单、短时、有亲缘关系的单向数据传递
它本质是内核中一块带缓冲区的“数据通道”,轻量、易用,但限制明显。
- 匿名管道只能用于父子或兄弟进程——因为子进程靠继承父进程的文件描述符才能访问同一管道
- 数据流单向,读写端需提前约定;若一端关闭,另一端继续读会返回EOF,继续写则触发SIGPIPE信号
- 缓冲区大小有限(通常64KB),写满或读空时默认阻塞,适合小批量、命令行式协作(如shell中
ls | grep .c) - 命名管道(FIFO)突破了亲缘限制,以文件路径为标识,任意进程只要知道路径就能打开读写,但仍保持单向和阻塞特性
消息队列适合需要结构化、异步、可靠传递的跨进程通信
它本质是内核维护的链表,每条消息自带类型标记,支持随机读取和优先级控制。
- 消息可带类型字段,接收方能按需获取指定类型的消息,不必严格遵循发送顺序
- 消息体有长度限制(如MSGMAX,默认8KB),但比管道更灵活,支持非字节流数据(比如打包好的struct)
- 即使接收进程暂时未启动,消息仍保留在内核队列中(除非被显式删除或系统重启),具备一定持久性
- 适用于任务分发、日志聚合、状态通知等场景,比如一个监控进程向多个处理模块广播告警事件
共享内存适合高频、大数据量的低延迟共享访问
它本质是把一段物理内存映射到多个进程的虚拟地址空间,数据不复制、不穿越内核,因此最快。
- 没有内核中转开销,读写直接操作内存地址,吞吐量远高于管道和消息队列
- 但不提供同步能力——必须搭配信号量、互斥锁或futex等机制,防止多个进程同时读写导致数据错乱
- 生命周期独立于进程,需显式删除(
shmctl(..., IPC_RMID)),否则残留会占用系统资源 - 典型用例包括实时音视频处理、高频交易数据缓存、图形渲染共享帧缓冲等对性能极度敏感的场景
不复杂但容易忽略:没有万能方案。父子进程传几行日志,用管道就够了;多服务模块解耦通信,消息队列更稳;而两个计算密集型进程反复交换百万级数组,共享内存几乎是唯一选择。