进程之间怎么聊天?信号、管道、共享内存、Socket 大乱斗!

------ 小dora 操作系统学习笔记 Vol.5 · 进程通信篇(IPC)


dora:"我创建了两个进程,咋让它们对话?"

操作系统冷冷一笑:"进程是天生孤独的,但我给你桥梁。"

本章目标是:让你轻松理解操作系统中**进程通信(Inter-Process Communication, IPC)**的几种典型方式------信号、管道、共享内存、Socket,并且知道什么时候该用谁,背后又是啥机制。


🧠 一、进程为什么不能直接对话?

操作系统的"内存隔离机制"决定了:

  • 每个进程都有独立的虚拟地址空间
  • 你无法直接访问另一个进程的变量、堆或栈

所以:必须借助操作系统提供的"中介"来通信,这就是 IPC。

📌 巧记口诀:

"进程像独立公寓,交流靠物业搭电梯。"


🔔 二、信号(Signal):最基础的通信方式

信号本质上是一个"异步中断",用于通知进程发生了某个事件。

常见信号:

信号编号 名称 含义
2 SIGINT Ctrl+C 中断
9 SIGKILL 强制杀死进程
15 SIGTERM 请求终止进程
17/18/20 SIGCHLD 子进程退出通知

特点:

  • 轻量级,无需共享资源
  • 通信粒度小,不能传输数据(只能传 signal)

📌 常用于:中断处理、父子进程通知、定时任务

📌 巧记口诀:

"信号像微信提醒,只能告诉你'有事',不能说'啥事'。"


🧵 三、管道(Pipe):标准 I/O 的串联通道

3.1 匿名管道

arduino 复制代码
int pipe(int fd[2]);
  • fd[0]:读端
  • fd[1]:写端

用于具有亲缘关系的进程(如父子)

📌 示例:

shell 复制代码
$ ls | grep .txt

Shell 实际上:

  • fork 出两个子进程
  • 用 pipe 把 ls 的 stdout 和 grep 的 stdin 串起来

📌 特点:

  • 单向
  • 仅限父子进程

3.2 命名管道(FIFO)

bash 复制代码
mkfifo mypipe
  • 可用于任意两个进程(不一定有亲缘关系)
  • 存在于文件系统中,类似设备文件

📌 巧记口诀:

"匿名管道像耳语,只能和亲人讲;命名管道像喇叭,大家都能听。"


🧠 四、共享内存(Shared Memory):最快的通信方式

"你不许动我空间,但我允许你搬来一起住。"

共享内存是多个进程共享一块物理内存区域

ini 复制代码
int shmid = shmget(key, size, IPC_CREAT);
void* addr = shmat(shmid, NULL, 0);

优点:

  • 不需要数据拷贝(零拷贝)
  • 快到飞起,常用于实时系统、数据库、图像处理

缺点:

  • 不安全,需额外同步机制(信号量、互斥锁)

📌 巧记口诀:

"共享内存像情侣合租,快是快,但吵架频繁要协调。"


⚖️ 五、信号量(Semaphore):共享内存的好搭档

  • 本质:一个整型变量 + PV 操作
  • 用于控制共享资源的访问顺序,避免竞态条件(race condition)
scss 复制代码
sem_wait(&sem);   // P操作,等待资源
sem_post(&sem);   // V操作,释放资源

📌 常与共享内存配合使用

📌 巧记口诀:

"你用锅我用铲,排好队不打架。"


🌐 六、Socket 通信:远程/本地皆可聊

Socket 是最强大的 IPC:

  • 可以进程内通信(UNIX 域 Socket)
  • 也可以跨主机通信(TCP/IP)
scss 复制代码
socket() → bind() → listen() → accept()

或:在 Node.js 中这样写:

ini 复制代码
const net = require('net');
const server = net.createServer(socket => {
  socket.write('hello client');
});
server.listen(8080);

📌 巧记口诀:

"Socket 是全球通,跨城跨国都能通。"


🔍 七、总结对比:选谁好?

方式 是否可跨主机 是否传数据 速度 使用场景
信号 Signal 中断、通知
管道 Pipe 父子、串联任务
共享内存 ✅✅ 最快 数据库、实时系统
Socket 中等 网络通信、服务端

📌 巧记口诀:

"信号吼一声,管道说一句,内存放全文,Socket 发快递。"


🧪 面试练习题

Q1:进程之间不能直接访问彼此内存的原因?

✅ 答案:虚拟地址空间隔离(保护性设计)


Q2:哪种 IPC 方式最快?为何?

✅ 答案:共享内存;因无需拷贝、直接访问物理页


Q3:Socket 为何可以跨主机?

✅ 答案:基于网络协议栈,使用 IP + 端口通信


Q4:信号量是做什么用的?

✅ 答案:同步访问共享资源,防止竞态条件


✅ 总结:

"进程各自为战,通信靠中介;哪种方式靠谱,还得看场景!"


相关推荐
请输入蚊子1 天前
«操作系统真像还原» 第二章 编写MBR主引导记录
linux·汇编·操作系统·bochs·操作系统真像还原
添砖java‘’2 天前
线程的互斥与同步
linux·c++·操作系统·线程·信息与通信
燃于AC之乐3 天前
【Linux系统编程】进程控制完全指南:从fork创建、优雅终止到进程等待的全面解析
linux·操作系统·进程控制·进程创建·进程等待·进程终止·fork函数
Trouvaille ~3 天前
【Linux】Linux线程概念与控制(四):glibc源码剖析与实现原理
linux·运维·服务器·c++·操作系统·glibc·线程控制
_OP_CHEN4 天前
【Linux系统编程】(二十四)深入 Ext2 块组内部:inode、数据块与目录的底层工作机制
linux·操作系统·文件系统·c/c++·inode·块组·数据块映射
番茄灭世神4 天前
Linux从入门到进阶第一章
linux·计算机·操作系统
燃于AC之乐5 天前
【Linux系统编程】进程地址空间完全指南:页表、写时拷贝与虚拟内存管理
linux·操作系统·虚拟内存·进程地址空间
_OP_CHEN5 天前
【Linux系统编程】(二十三)从块到块组:Ext2 文件系统核心架构的初步认识
linux·操作系统·文件系统·c/c++·ext2文件系统·磁盘分区·块组
Byte不洛5 天前
Linux 多线程编程入门:线程栈、TLS、互斥锁与条件变量详解
linux·操作系统·多线程·pthread·线程互斥
_OP_CHEN6 天前
【Linux系统编程】(二十二)从磁盘物理结构到地址映射:Ext 系列文件系统硬件底层原理深度剖析
linux·操作系统·文件系统·c/c++·计算机硬件·ext文件系统·磁盘寻址