为了能强化在Linux上的开发体验和熟练度,我打算尽量全面地总结一下Linux下能用的IPC方式。
部分由DeepSeek R1解释
System V IPC
System V是Unix的一个早期版本,其引入的许多特性成为类Unix的一部分,甚至影响到了POSIX规范的制定,IPC也是其中之一。
但是由于System V的IPC方式设计时代久远、可能产生局限,因此新的项目并不推荐使用此类IPC方式。
Message Queues
API Examples
- msgget
- msgsnd
- msgrcv
- msgctl
Semaphores
API Examples
- semget
- semop
- semctl
Shared Memory
API Examples
- shmget
- shmat
- shmdt
- shmctl
POSIX IPC
推荐使用,符合现代情景。
Message Queues
API Examples
- mq_open
- mq_send
- mq_receive
Semaphores
API Examples
- sem_open
- sem_wait
- sem_post
Shared Memory
API Examples
- shm_open
- shm_unlink
Unix Domain Socket
使用AF_UNIX
配置socket。
Pipe/FIFO
API Exmaples
- mkfifo
- pipe
mmap
- mmap一个匿名内存后再进行fork,可以实现parent/child process之间的内存共享。
- 或者通过mmap同一个文件来共享内存,但是可能会遇到缓存问题。
其他
DBus
各类RPC框架
process_vm_readv/process_vm_writev
syscall直接访问另一个进程的虚拟内存,非特殊情况下不推荐,仅为Linux的syscall,非正常IPC行为。
总结对比
忽略System V IPC API,他们均可被POSIX V API替代。
机制 | 性能 | 适用场景 | 易用性 | 数据格式支持 | 备注 |
---|---|---|---|---|---|
POSIX shm | 高 | 高频大数据交换,可持久化共享内存 | 复杂 | 无结构,双向 | 需同步机制,生命周期独立于进程 |
Unix Domain Socket | 高 | 结构化数据、可靠通信 | 中等 | 字节流,支持结构化协议,双向 | 高性能本地通信,支持权限控制,Windows10 17063后提供部分支持 |
Pipe/FIFO | 中 | 简单线性数据传输 | 简单 | 字节流,单向 | Pipe只用于具亲缘关系的进程,FIFO为半双工传输方式,通过命名文件支持非亲缘 |
POSIX msg queue | 中 | 优先级消息、持久化消息队列 | 中等 | 消息块(有边界) | 消息带优先级,需内核配置支持 |
D-Bus | 中 | 桌面应用、服务调用 | 中等 | 复杂对象模型 | 上层应用,需安装libdbus库。基于UDS实现,适合高层抽象(deepseek) |
信号 | 高 | 简单通知或控制 | 简单 | 无数据或少量数据 | SIGRTMIN 可通过sigqueue 发送附加数据 |
文件内存映射 | 高 | 大文件或持久化数据 | 复杂 | 无结构,双向 | 将经过磁盘IO,且可能产生缓存问题 |
匿名内存映射 | 高 | 亲缘进程ipc | 中等 | 无结构,双向 | 也可通过memfd 跨非亲缘进程共享。(deepseek) |
RPC(如 gRPC) | 高 | 跨语言、分布式系统 | 复杂 | 结构化数据 | 本地或网络通信,依赖序列化 |
process_vm_* | 高 | 仅调试,逆向 | 复杂 | 无结构 | 直接读写其他进程内存,非标准IPC |
综上,根据不同环境选择合适机制:
发送优先级消息:采用消息队列
高性能零拷贝:优先选择POSIX共享内存或匿名内存映射(亲缘进程)。
前后端分离,后端可远程部署/数据通信经过网络或本地/全双工:使用Unix Domain Socket。
- docker
- VS Code
简单通知:信号(实时信号可携带数据)。
- 例如goroutine切换中断通知
跨主机/语言:RPC框架(如gRPC)。
桌面服务通信:D-Bus(如系统服务调用)。
进程间简单通信:pipe/FIFO