Linux IPC 进程间通信总结

IPC(Inter‑Process Communication)进程间通信,用于实现同一台主机上不同进程之间的数据交互。进程用户空间互相独立,不能直接访问,通信必须借助操作系统内核提供的机制。

IPC 分为三大类:

  1. 传统古老通信:无名管道、有名管道、信号
  2. System V IPC 对象:共享内存、消息队列、信号量集
  3. Socket:支持本机 / 跨主机网络通信

1. 无名管道 pipe

  • 适用范围:仅亲缘进程(父子进程)
  • 创建:pipe(fd[2])fd[0]读端,fd[1]写端
  • 本质:内核缓冲区,默认 64K,FIFO 先进先出
  • 特点
    1. 写阻塞:当管道的读写端都存在时,管道写满数据时,发生写阻塞。
    2. 读阻塞:当管道的读写端都存在时,管道为空时,读管道发生读阻塞。
    3. 读返回0:当管道没有写端,只有读端时,管道中有数据则读出数据,无数据时,不再读阻塞,读 管道直接返回0字节。
    4. 管道破裂:当管道没有读端,向管道中写数据,发生管道破裂异常。
  • 使用流程:pipe()创建 → read()读 / write()写 → close()关闭文件描述符

2. 有名管道 FIFO

  • 适用范围:本机任意进程,不需要亲缘关系
  • 创建:mkfifo()生成管道文件,存放在文件系统
  • 使用流程:mkfifo()创建管道文件 → open()打开 → read() / write()读写 → close()关闭

和无名管道内核行为一致,区别是有实体文件,非亲缘进程可以通过文件名打开通信。

3. 信号 signal

  • 本质:异步软中断通知机制,不携带大量业务数据,用来通知进程发生某个事件。
  • 常见信号
    • SIGINT Ctrl+C,终止进程
    • SIGKILL 强制杀死进程,不能被捕获忽略
    • SIGCHLD 子进程退出时发送给父进程
    • SIGUSR1 / SIGUSR2 用户自定义信号
  • 信号三种处理方式
    1. 忽略:SIG_IGN
    2. 默认处理:SIG_DFL(大多直接杀死进程)
    3. 捕获:注册自定义回调函数处理信号
  • 核心 API
    • signal():注册信号处理函数
    • kill(pid,sig):向指定进程发送信号
    • alarm(sec):定时,到期发送 SIGALRM
    • pause():进程休眠,等待信号唤醒

4. System V — 消息队列

  • 内核维护消息链表,数据按消息类型收发,可以按类型选择性读取消息,实现简单消息优先级。

  • 操作步骤
  1. ftok():生成 IPC 唯一 key
  2. msgget():创建 / 获取消息队列 ID
  3. msgsnd():发送消息(携带消息类型 + 消息正文)
  4. msgrcv():按类型接收消息
  5. msgctl(IPC_RMID):删除消息队列
  • 系统命令查看:ipcs -a;删除:ipcrm -q

缺点:拷贝次数多,大数据传输效率一般。

5. System V — 共享内存(效率最高 IPC)

  • 原理:把同一块内核内存,映射到多个进程用户虚拟地址空间,进程直接读写这块内存,减少数据拷贝
  • 操作步骤
  1. ftok()生成 key
  2. shmget()创建共享内存,返回 shmid
  3. shmat()挂载映射到进程用户空间,得到内存指针,直接读写
  4. shmdt()解除映射
  5. shmctl(IPC_RMID)销毁共享内存

⚠️共享内存本身没有同步互斥机制,多进程读写需要搭配信号量 / 互斥锁做保护,防止数据竞争。

6. System V — 信号量集

  • 作用:进程间同步、互斥,不传输业务数据,用来保护临界资源。
  • 本质:内核维护一组计数器(信号量数组)
  • P 操作(申请资源,计数器‑1);V 操作(释放资源,计数器 + 1)。

7. Socket 通信

  • 既可以本机进程通信,也可以跨主机网络通信
  • 分为 UDP、TCP 套接字;本地 Unix 域 socket 专门用于本机 IPC。
Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐