管道
父子进程通信
管道 是 CoddyKit 上的免费 C Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C Academy 课程共包含 4 节课。
什么是管道
管道是相关进程之间的单向通信通道。一个进程将字节写入管道,另一个进程将其读出,就像数据传送带一样。
两个文件描述符
pipe() 调用会填充一个包含两个元素的数组:fd[0] 是读端,fd[1] 是写端。写入 fd[1] 的数据可以从 fd[0] 读取。
#include <unistd.h>
#include <stdio.h>
int make_pipe(int fd[2]) {
if (pipe(fd) < 0) { perror("pipe"); return -1; }
/* fd[0] read end, fd[1] write end */
return 0;
}与 fork 结合使用
执行 fork() 后,父进程和子进程共享管道的描述符。父进程与子进程正是通过这种方式通信的:一方写入,另一方读取。
关闭未使用的端
每个进程都应关闭自己不使用的一端。读取方关闭写端,写入方关闭读端。否则,读取方永远不会看到文件结束。
#include <unistd.h>
void parent_as_writer(int fd[2]) {
close(fd[0]); /* parent will not read */
write(fd[1], "hello", 5); /* parent writes */
close(fd[1]); /* signal EOF to reader */
}父子进程示例
父进程写入一条消息,子进程读取它。双方各自关闭不需要的一端。
#include <unistd.h>
#include <stdio.h>
void demo(int fd[2]) {
if (fork() == 0) { /* child: reader */
close(fd[1]);
char buf[64];
ssize_t n = read(fd[0], buf, sizeof buf - 1);
buf[n] = 0;
printf("child got: %s\n", buf);
close(fd[0]);
} else { /* parent: writer */
close(fd[0]);
write(fd[1], "hi child", 8);
close(fd[1]);
}
}读取返回 EOF
当所有写端都关闭后,read 会返回 0,表示文件结束。如果仍有一个写端保持打开状态,读取方就会一直阻塞,等待更多数据;这是一个常见错误。
管道容量与阻塞
管道具有有限的缓冲区(通常为 64 KB)。缓冲区填满后,write 会阻塞,直到读取方取走数据。缓冲区为空时,read 会阻塞,直到数据到达。这种流量控制可以同步两个进程。
使用 dup2 重定向
dup2 可以将进程的标准输入或标准输出替换为管道的一端。Shell 正是通过这种方式实现 cmd1 | cmd2 的,将一个命令的输出连接到下一个命令的输入。
#include <unistd.h>
void stdout_to_pipe(int fd[2]) {
close(fd[0]);
dup2(fd[1], STDOUT_FILENO); /* writes to stdout go into pipe */
close(fd[1]);
}命名管道(FIFO)
普通管道只能连接相关进程。使用 mkfifo 创建的命名管道(FIFO)会出现在文件系统中,因此不相关的进程也可以通过路径打开它并进行通信。
#include <sys/stat.h>
int make_fifo(const char *path) {
return mkfifo(path, 0666); /* creates a FIFO file */
}SIGPIPE 风险
向读端已关闭的管道写入数据会触发 SIGPIPE,默认情况下会终止进程。您可以忽略此信号,或者检查 write 返回的 EPIPE 错误。
何时使用管道
管道非常适合父进程与子进程之间进行简单的单向流式通信,也适合将多个程序串联起来。对于双向通信或不相关进程之间的通信,请考虑使用 FIFO、套接字或共享内存。
快速检查
测试您对管道的理解。
回顾
您学会了使用管道进行父子进程通信。
pipe()提供 fd[0](读端)和 fd[1](写端)- 与
fork结合使用;关闭未使用的端 - 所有写端关闭后,read 在 EOF 处返回 0
- FIFO 可以连接不相关的进程;请注意 SIGPIPE
常见问题解答
「管道」课时是免费的吗?
是的 — 「管道」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C Academy 课程的其余内容,请升级到 CoddyKit PRO。 C Academy 课程共包含 4 节课。
「管道」这节课中我会学到什么?
父子进程通信 你通过在浏览器中直接运行的动手代码来练习 C Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 C Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 C Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「管道」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 C Academy 课中编写并运行代码吗?
能。每节 C Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。