一、六大 IPC 方式
| 方式 | 特点 | 速度 | 场景 |
|---|---|---|---|
| 管道 Pipe | 半双工,仅父子进程 | 中 | 简单父子通信 |
| 命名管道 FIFO | 半双工,无亲缘关系 | 中 | 跨进程文件式通信 |
| 消息队列 | 有格式消息链表 | 中 | 结构化消息 |
| 共享内存 | 零拷贝,需同步 | 最快 | 大数据量频繁通信 |
| 信号量 | 同步/互斥 | 快 | 配合共享内存 |
| Socket | 可跨主机 | 慢 | 网络通信 |
二、为什么共享内存最快
管道: A → 内核缓冲 → B (两次拷贝)
共享内存: A → 同一物理页 ← B (零拷贝)
面试话术:
"共享内存把同一块物理内存映射到两个进程的地址空间,之后直接读写,数据不经过内核中转。管道要经历写端到内核、内核到读端两次拷贝。共享内存只需要一次映射,后续零拷贝,所以最快。"
三、信号量 vs 互斥锁
| 互斥锁 | 信号量 | |
|---|---|---|
| 用途 | 互斥 | 同步 + 互斥 |
| 值域 | 0/1 | 任意非负整数 |
| 加解锁者 | 必须同线程 | 可不同线程 |
| 优先级继承 | ✅ | ❌ |
面试话术:
"互斥锁是二元的,谁加锁谁解锁,有优先级继承。信号量值可以大于 1,生产者 V 消费者 P,不需要同一个线程解锁。互斥锁解决临界区保护,信号量还能做资源计数和事件通知。"
四、Unix 域套接字 vs TCP
为什么 Unix Domain Socket 比 TCP 快:
| 原因 | 说明 |
|---|---|
| 不走协议栈 | 无 IP/TCP 头部、无校验和、无拥塞控制 |
| 拷贝少 | 内核直接内存传递 |
| 能传 fd | SCM_RIGHTS 传递文件描述符,TCP 做不到 |
面试话术:
"Unix 域套接字同主机进程间通信首选。它绕过了 TCP/IP 协议栈,没有报文头、校验和、拥塞控制这些开销,而且能传递文件描述符。性能比 TCP 环回高很多。"
五、大华追问:共享内存+信号量 vs Socket
| 共享内存+信号量 | Socket | |
|---|---|---|
| 速度 | 最快(零拷贝) | 慢(协议栈+拷贝) |
| 范围 | 仅同主机 | 可跨主机 |
| 同步方式 | 手动(信号量) | 协议内置 |
| 编程复杂度 | 高 | 低 |
面试话术:
"本地多进程传视频帧用共享内存——3MB 一帧零拷贝。跨设备用 Socket——标准的 RTSP/RTP 协议通信。嵌入式本地通信选共享内存,需要网络跨机选 Socket。"
六、音视频方向的实际场景
场景1:采集进程 → 编码进程(本地,大帧数据)
选共享内存:映射帧缓冲到两个进程,零拷贝
场景2:编码进程 → 推流进程(本地,码流数据)
选共享内存或 Unix 域套接字
场景3:推流进程 → 服务器(跨主机)
选 TCP/UDP Socket:RTSP 信令 + RTP 数据
面试话术:
"我的项目里采集和编码如果是独立进程,帧数据用共享内存传——零拷贝性能最高。推流到远端走 Socket——RTSP over TCP,RTP over UDP。本地同步用信号量,跨网络协议栈用 Socket。"
七、高频面试题
Q:管道和共享内存的区别?
"管道是内核缓冲中转,两次拷贝,但自动同步;共享内存直接映射物理内存,零拷贝但需要手动同步。音视频大帧数据首选共享内存。"
Q:信号量怎么配合共享内存?
"信号量做计数器。采集进程写完一帧 V 操作信号量+1,编码进程 P 操作-1 后取帧,没有帧时阻塞等待。"
Q:为什么不用消息队列传视频帧?
"消息队列有长度限制,大数据要分条,且有内核拷贝。视频帧 3MB 一帧,用消息队列效率太低。共享内存零拷贝才是正解。"