版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/afei__/article/details/84106493
一、简介
管道(pipe) 是一种最基本的 IPC(Inter Process Communication) 机制,优点是简单。
二、特点:
- 管道只适用于 存在血缘关系 的两个进程之间通信,因为只有存在血缘关系的两个进程之间才能共享文件描述符
- 管道分为两端,一端读,一端写,有两个文件描述符分别表示读端和写端
- 管道是单向的,数据从写端输入,从读端取出
- 管道的本质是一个伪文件(实为内核缓冲区)
- 管道有容量限制,2.6.11 版本之前的 Linux 内核管道容量为 page size(4 Kb),之后版本改为 65535 字节
- 当管道满时,写端将堵塞。当管道空时,读端将堵塞
三、API 说明
1. 头文件
#include <unistd.h>
2. 创建并打开管道
int pipe(int pipefd[2]);
3. 参数说明
pipefd[0]
:读端的文件描述符
pipefd[1]
:写端的文件描述符
4. 返回值说明
成功返回 0
,失败返回 -1
,并设置相应的 errno
。
四、示例
下面演示一个,父进程往管道写入数据,子进程从管道读出数据并输出到标准输出流。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
int main() {
int pipe_fd[2]; // pipe_fd[0] 表示读端,pipe_fd[1] 表示写端
pid_t child_pid;
char buf[] = "Hello World";
if (pipe(pipe_fd) == -1) { // 创建管道
perror("pipe failed");
exit(EXIT_FAILURE);
}
child_pid = fork(); // 创建一个子进程
if (child_pid == -1) {
perror("fork failed");
exit(EXIT_FAILURE);
}
if (child_pid == 0) { // 根据 fork 的特点,child_pid 等于 0 表示子进程
close(pipe_fd[1]); // 子进程从管道读数据,所以关闭写端
while (read(pipe_fd[0], &buf, 1) > 0) { // 从读端读出数据
write(STDOUT_FILENO, &buf, 1); // 写入到标准输出流显示
}
close(pipe_fd[0]);
_exit(EXIT_SUCCESS);
} else { // 根据 fork 的特点,child_pid 大于 0 表示父进程
close(pipe_fd[0]); // 父进程从管道写数据,所以关闭读端
write(pipe_fd[1], &buf, strlen(buf)); // 往写端写入数据
close(pipe_fd[1]);
wait(NULL); // 等待并回收子进程
_exit(EXIT_SUCCESS);
}
return 0;
}