管道是类 Unix 系统中最经典的进程间通信方式,提供一个单向的字节流通道,一端写入、另一端读取。Shell 中的竖线符号就是匿名管道的应用,把前一个命令的输出接到后一个命令的输入;命名管道(FIFO)则以文件形式存在,可供无亲缘关系的进程使用。

| 所属领域 | 进程间通信 |
| 通信方向 | 半双工(单向) |
| 默认缓冲区 | 64KB(Linux) |
| 原子写上限 | PIPE_BUF=4096 字节 |
| 创建接口 | pipe / mkfifo |
管道(Pipe)是类 Unix 操作系统提供的一种进程间通信机制,由内核维护一段缓冲区,构成先进先出的单向字节流:一个进程从写端写入数据,另一个进程从读端按写入顺序读出。管道思想由道格拉斯·麦克罗伊(Douglas McIlroy)提出,1973 年由肯·汤普逊(Ken Thompson)实现进 Unix,成为 Unix 哲学中组合小工具完成复杂任务的基石。
管道分为两类。匿名管道通过 pipe 系统调用创建,返回一对文件描述符,通常配合 fork 在父子进程等有亲缘关系的进程间使用,shell 命令行中的竖线正是它最著名的应用。命名管道又称 FIFO,通过 mkfifo 创建,在文件系统中以特殊文件的形式存在,任何有权限的进程都可以打开它进行读写,因此适用于无亲缘关系的进程。
管道最大的舞台是 shell:把 grep、sort、uniq、awk 等小程序串成流水线,是 Unix 用户的日常操作。程序设计中,父进程常用管道读取子进程的输出,popen 函数正是对这一模式的封装;命名管道则常用于日志收集、简单的本机服务通信等场景。相比共享内存,管道无需同步原语、接口简单,但存在数据拷贝开销,吞吐要求极高的场景通常改用共享内存或 Unix 域套接字。
问:管道和重定向有什么区别?答:重定向把命令的输入或输出接到文件,管道把一个进程的输出直接接到另一个进程的输入,数据经内核缓冲区传递,不落盘。
问:为什么脚本里会遇到 Broken pipe 错误?答:当读端已经关闭(例如 head 读够行数后退出),写端继续写入就会收到 SIGPIPE 信号或得到 EPIPE 错误,这是管道的正常保护机制。
问:命名管道里的数据存在磁盘上吗?答:不存。FIFO 文件只是文件系统中的一个入口,数据仍然只经过内核内存缓冲区,进程读走即消失,管道关闭后不留痕迹。

| 所属领域 | 进程间通信 |
| 通信方向 | 半双工(单向) |
| 默认缓冲区 | 64KB(Linux) |
| 原子写上限 | PIPE_BUF=4096 字节 |
| 创建接口 | pipe / mkfifo |
登录 后参与讨论
暂无讨论,来发表第一条评论吧