Linux 管道通信详解
一、进程间通信基础
进程间通信(IPC)是操作系统中不同进程交换信息的关键机制,涉及数据传输、资源共享、事件通知及进程控制等场景。
常见的 IPC 方式包括管道、System V IPC 和 POSIX IPC。由于进程拥有独立的地址空间,实现通信的前提是它们能访问同一份共享资源。
二、管道机制
1. 什么是管道
管道是类 Unix 系统中最古老的 IPC 方式之一。它将一个进程的输出连接到另一个进程的输入,形成单向数据流,因此也称为单工通信。

管道主要分为两类:匿名管道和命名管道。
2. 匿名管道
匿名管道(pipe)主要用于有亲缘关系的进程之间(如父子进程)。它本质上是内核管理的一块内存区域,通过一对文件描述符实现读写分离,随进程退出自动销毁。
创建管道使用 pipe 系统调用,参数为文件描述符数组。成功返回 0,失败返回错误码。通常 fd[0] 为读端,fd[1] 为写端。


匿名管道没有文件名和路径,仅靠文件描述符传递,因此只能用于继承文件描述符表的亲缘进程间通信。
通信行为特点
- 阻塞机制:子进程写得慢,父进程会阻塞等待;子进程写得快且管道满时,子进程也会阻塞。
- EOF 处理:读端读完数据且写端关闭后,read 返回 0。
- 异常终止:若写端一直写而读端关闭,操作系统会向写端发送 SIGPIPE 信号(通常为 13),导致进程异常终止。
- 生命周期:管道是内核临时对象,当所有持有描述符的进程关闭后自动销毁。
- 同步互斥:多进程通信自带同步机制,读空或写满时会自动阻塞。
代码示例
下面是一个简单的匿名管道通信示例,演示父子进程间的数据传输:
#include <stdio.h>
#include <stdlib.h>
#include
{
pipefd[] = {};
((pipefd) != ) {
();
}
(, pipefd[], pipefd[]);
id = fork();
(id == ) {
(pipefd[]);
*msg = ;
cnt = ;
outbuffer[];
(cnt) {
(outbuffer, (outbuffer), , msg, cnt--);
(pipefd[], outbuffer, (outbuffer));
();
}
(pipefd[]);
();
} {
(pipefd[]);
inbuffer[];
() {
inbuffer[] = ;
n = (pipefd[], inbuffer, (inbuffer) - );
(n > ) {
inbuffer[n] = ;
(, inbuffer);
} (n == ) {
();
(pipefd[]);
;
} {
();
;
}
}
(id, , );
}
;
}






