主题
概念卡片:进程间通信与线程同步
一句话机制:进程地址空间隔离 → 需要 IPC 交换数据;线程共享地址空间 → 无需「通信」但要「同步/互斥」保护共享变量。IPC 是操作系统保证的系统调用,线程同步靠锁/信号量/事件。
进程间通信(IPC)七种方式
| 方式 | 特点 | 适用 |
|---|---|---|
| 管道 pipe | 半双工、数据单向、无名 | 父子/兄弟进程 |
| 有名管道 named pipe | 半双工、以磁盘文件存在 | 本机任意两进程(FIFO) |
| 信号 signal | 通知「事件已发生」 | 简单通知 |
| 消息队列 message queue | 消息链表、存内核、可随机查询/按类型读 | 克服信号信息少、管道无格式/缓冲小 |
| 信号量 semaphore | 计数器,控制多进程访问共享资源 | 同步/互斥 |
| 共享内存 shared memory | 多进程访问同一块内存 | 最快的 IPC,需配信号量同步 |
| 套接字 socket | 跨网络、不同主机进程通信 | 客户端/服务器 |
线程间同步方式
| 方式 | 机制 |
|---|---|
| 互斥量 Mutex | 排他访问,只有拥有者能访问(synchronized/Lock) |
| 信号量 Semaphore | 允许多线程访问,但控制最大并发数 |
| 事件 Event(Wait/Notify) | 通知机制,实现同步与优先级比较 |
线程通信目的主要是同步,所以没有像进程那样的数据交换机制(因为已共享内存)。
进程通信 vs 线程通信(根本区别)
| 进程间 | 线程间 | |
|---|---|---|
| 是否需要通信 | 需要(地址空间隔离) | 不需要(已共享) |
| 需求 | 数据交换 | 同步/互斥 |
| 手段 | 管道/消息队列/共享内存等系统调用 | 锁/信号量/事件 |
| 共享变量 | 无需同步 | 必须同步 |
关键代码示例(线程同步)
死锁场景(互斥锁嵌套,破坏循环等待后修复):
java
// 线程 2 按同一顺序申请资源,避免循环等待
new Thread(() -> {
synchronized (resource1) {
System.out.println(Thread.currentThread() + "get resource1");
synchronized (resource2) {
System.out.println(Thread.currentThread() + "get resource2");
}
}
}, "线程 2").start();不变量(必须成立的约束)
- 共享内存是最快的 IPC,但必须配合信号量/互斥锁做同步。
- 线程共享地址空间,操作公共变量必须同步(锁/信号量),否则数据竞争。
- 管道是半双工、消息队列可随机读取——这是两者的关键差异。
常见误解
- 以为「线程也需要通信」→ 线程共享内存,只需同步,无需数据交换型通信。
- 以为「信号量只能互斥」→ 信号量是计数器,既能互斥也能控制并发上限。
- 以为「管道和消息队列没区别」→ 管道只承载无格式字节流且缓冲受限,消息队列存内核、可按类型读。
关联
- 进程线程:概念卡片:进程与线程
- 死锁:概念卡片:死锁
- 总览:操作系统技术栈总览