进程间通信(IPC)方式
📋 进程间通信(IPC)方式大全 (Unix/Linux)
通信方式 | 核心原理 | 关键C语言系统调用/函数 | 主要特点与适用场景 |
---|---|---|---|
1. 匿名管道 (Pipe) | 内核缓冲区,单向字节流 | pipe() | 仅限于有亲缘关系的进程;单向通信;简单易用。 |
2. 命名管道 (FIFO) | 一个有名字的管道,存在于文件系统 | mkfifo() , open() , read() , write() , close() | 可用于无亲缘关系进程;通过文件路径名访问;仍然通常是单向的。 |
3. 消息队列 (Message Queue) | 内核维护的消息链表,按类型读取 | msgget() , msgsnd() , msgrcv() , msgctl() | 消息有格式和优先级;可以非阻塞地读取;独立于进程存在(持久性)。 |
4. 共享内存 (Shared Memory) | 多个进程共享同一块物理内存 | shmget() , shmat() , shmdt() , shmctl() | 速度最快的IPC;需要与信号量等同步机制配合使用,防止数据混乱。 |
5. 信号 (Signal) | 内核向进程发送的异步事件通知 | signal() , sigaction() , kill() , raise() | 携带的信息量少(只有一个编号);主要用于控制进程行为(如终止、暂停),而非大数据交换。 |
6. 信号量 (Semaphore) | 一个用于进程间同步的计数器 | semget() , semop() , semctl() | 不是用来传输数据的,而是用来协调多个进程对共享资源的访问,常与共享内存配套使用。 |
7. 套接字 (Socket) | 最通用的通信端点,支持网络和单机 | socket() , bind() , listen() , accept() , connect() , send() , recv() | 功能最强大,可用于不同主机间的进程通信;同一主机上也可用(Unix Domain Socket效率很高)。 |
8. 内存映射文件 (mmap) | 将文件直接映射到进程地址空间 | mmap() , munmap() | 既可实现进程间通信(设置共享标志),也可用于高效文件IO。 |
💡 如何选择与学习建议
性能极致(同一主机):首选 共享内存 + 信号量。这是大数据量、高频交换场景的黄金组合,但同步逻辑最复杂。
结构化消息:使用 消息队列。适合需要按类别或优先级处理离散命令或数据的场景。
简单数据流:使用 管道(父子进程用匿名,无关系进程用命名)。
进程控制:使用 信号。例如,优雅地终止一个后台服务进程。
通用性与网络通信:必须使用 套接字。无论是本地还是远程通信,这是最统一的方案。
学习路径建议:
对于初学者,建议按以下顺序实践,以逐步理解复杂度:
匿名管道 (Pipe) -> 命名管道 (FIFO) -> 信号 (Signal) -> 共享内存 & 信号量 -> 消息队列 -> 套接字 (Socket)。