Solaris 进程间通信(IPC)实验教程 — IPC 机制全解

基本信息

  • 来源: 田浩然上传的资料 / 0B104 操作系统高级课程 / Solaris实验 / Chap05_IPC_doc.pdf
  • 页数: 30 页,text_based PDF
  • 性质: 操作系统高级课程第 5 章实验讲义,Solaris 10 环境,中文,含完整 C 代码实例

章节结构

  • 5.1 概述 / 5.2 管道与命名管道 / 5.3 消息队列 / 5.4 共享内存 / 5.5 门(Doors)/ 5.6 小结 / 5.7 思考题 / 5.8 参考资料

核心知识

IPC 体系谱系

  • 最初 Unix IPC: 管道、FIFO、信号
  • System V IPC(AT&T 贝尔实验室路线,限单机内): System V 消息队列、信号量、共享内存区
  • POSIX IPC: POSIX 消息队列、信号量、共享内存区(Solaris 从开始就遵循 POSIX)
  • BSD 路线: Socket(可跨机);Solaris 两者都继承
  • 信号/信号量偏同步互斥,套接字走网络接口,门(Doors)是 Solaris 特有

管道(Pipe)

  • POSIX 管道半双工;Solaris(SVR4 系)管道基于 STREAMS,是全双工的——这是很多人不知道的细节
  • 仅限亲缘进程;自成一种只存在于内存中的独立文件系统
  • 读写规则(关键):
    • 双端都打开时读写均不确定,惯例是父子各自关闭一端
    • 写端关闭 → 读端读完缓冲后返回 0(EOF)
    • 读端关闭 → 写入收到 SIGPIPE;忽略则 write 返回 -1、errno=EPIPE
    • 单次写入 ≤ PIPE_BUF 字节保证原子性(不与其他写进程数据交叉)
  • 局限:仅亲缘进程、无名、缓冲区仅一页大小、无格式字节流需双方约定格式

命名管道(FIFO)

  • mkfifo(path, mode);有路径名,无亲缘进程也可通信
  • 打开规则:未设 O_NONBLOCK/O_NDELAY 时,只读 open 阻塞到有写者打开(反之亦然);设了非阻塞则只读 open 立即返回,只写 open 无读者时返回 ENXIO
  • 读写规则同管道;因常有多个写者,PIPE_BUF 原子性问题更突出
  • 不支持 lseek 等定位操作

消息队列(System V)

  • 内核常驻消息链表,随内核持续(kernel-persistent),区别于管道/信号的”随进程持续”
  • 克服信号信息量有限、管道无格式字节流且缓冲区受限的缺点
  • 消息带格式和优先级;内核数据结构 struct msqid_ds 是所有消息队列的访问入口
  • 分 POSIX 与 System V 两类

共享内存

  • 最快的 IPC:避免其他 IPC 的大量缓冲复制。管道/消息队列需内核-用户空间 4 次拷贝;共享内存只需 2 次(输入文件→共享区→输出文件)
  • 同一物理内存映射进多个进程地址空间(虚拟地址可不同);必须配合同步机制(互斥锁/信号量)
  • Solaris 10 支持 mmap()、POSIX 共享内存、System V 共享内存三种
  • System V 路径:shmget 创建/获取共享区并同时在内核建 shmid_ds 控制结构 + 在特殊文件系统 shm 中创建同名文件——共享内存是存储管理与文件系统结合的桥梁
  • 实践上保持映射直到通信完毕,内容在解除映射时才写回文件

门(Doors)— Solaris 特有,本文最有特色的部分

  • Solaris 2.6 引入,为同机客户-服务器间快速 RPC 提供机制,是 IPC 与 RPC 的综合
  • 基于用户线程级 → 省内存、提高内存使用效率;典型用途:用户认证(服务端获取客户端证书)、在线翻译系统(词库放服务端共享)
  • 工作方式:服务器进程创建门并绑定到文件(类似 FIFO,常放 /tmp),客户端打开该文件即连接到门;每次客户调用由服务器进程中一个线程处理,线程由门函数库自动管理
  • 门服务器是并发服务器,线程安全由内核保证
  • 三个核心函数:door_create()、fattach()(绑定文件)、door_return()(回复)
  • 实验用 dtrace 跟踪验证服务端互斥访问的线程安全性;高级功能支持描述符交换、传递口令/文件路径

讲义的工程建议(5.6 小结,观点鲜明)

  • 管道和 FIFO 是每天都在用的根本构件,值得精通
  • 新应用程序应尽量避免 System V 消息队列和信号量,改用全双工管道和文件锁(更简单)
  • 共享内存段有应用场合,mmap 能提供同样功能

思考题(值得做的实验)

  1. 父进程写管道后不关闭读端立即读取,子进程 3 秒后读到什么?
  2. 多个写子进程且单次写入超过 PIPE_BUF 时的数据交叉现象(getconf PIPE_BUF 查上限)

参考资料亮点

  • Solaris Internals / Solaris Performance and Tools(McDougall & Mauro [& Gregg])
  • Stevens《UNIX 网络编程 第二卷:进程间通信》《UNIX 环境高级编程》
  • 毛德操《Linux 内核源代码情景分析》(对 Solaris 内核也有很好分析)

关联

  • 与 APUE-unix环境高级编程 的 IPC 章节互补(本讲义偏 Solaris/STREAMS 视角)
  • 门的机制是 Solaris 独有知识点,与通用 Linux IPC 教程形成对照