Linux 管道(pipe)详细介绍
在 Linux 系统中,管道是一种用于进程间通信(IPC)的机制,它允许一个进程将数据输出到另一个进程的输入。管道有两种主要类型:匿名管道和命名管道(FIFO)。下面详细介绍 pipe
系统调用及其相关函数的使用方法,并提供示例、编译命令和输出结果。此外,我们将对比管道与其他 IPC 方法(如 Boost 库中的实现方式)。
1. 匿名管道(Anonymous Pipe)
1.1 创建管道
系统调用:pipe()
- 原型:
int pipe(int pipefd[2]);
- 参数:
pipefd
:一个包含两个整数的数组。pipefd[0]
用于读操作,pipefd[1]
用于写操作。
- 返回值:
- 成功:返回 0
- 失败:返回 -1,设置
errno
以指示错误
示例代码:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main() {
int pipefd[2];
pid_t pid;
char buf[100];
if (pipe(pipefd) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
}
pid = fork();
if (pid == -1) {
perror("fork");
exit(EXIT_FAILURE);
}
if (pid == 0) { // 子进程
close(pipefd[1]); // 关闭写端
read(pipefd[0], buf, sizeof(buf));
printf("Child read: %s\n", buf);
close(pipefd[0]);
exit(EXIT_SUCCESS);
} else { // 父进程
close(pipefd[0]); // 关闭读端
write(pipefd[1], "Hello from parent", 18);
close(pipefd[1]);
wait(NULL); // 等待子进程
exit(EXIT_SUCCESS);
}
}
1.2 编译命令
gcc -o pipe_example pipe_example.c
1.3 例程输出
Child read: Hello from parent
2. 命名管道(Named Pipe, FIFO)
2.1 创建命名管道
系统调用:mkfifo()
- 原型:
int mkfifo(const char *pathname, mode_t mode);
- 参数:
pathname
:管道文件的路径mode
:权限模式(如 0666)
- 返回值:
- 成功:返回 0
- 失败:返回 -1,设置
errno
以指示错误
示例代码:
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#define FIFO_NAME "/tmp/myfifo"
int main() {
int fd;
char buf[100];
// 创建命名管道
if (mkfifo(FIFO_NAME, 0666) == -1) {
perror("mkfifo");
exit(EXIT_FAILURE);
}
// 写入数据
fd = open(FIFO_NAME, O_WRONLY);
write(fd, "Hello via FIFO", 15);
close(fd);
// 读取数据
fd = open(FIFO_NAME, O_RDONLY);
read(fd, buf, sizeof(buf));
printf("Read from FIFO: %s\n", buf);
close(fd);
// 删除命名管道
unlink(FIFO_NAME);
return 0;
}
2.2 编译命令
gcc -o fifo_example fifo_example.c
2.3 例程输出
Read from FIFO: Hello via FIFO
3. 管道与其他进程间通信方式的比较
3.1 管道的优缺点
优点:
- 简单易用:创建和使用管道简单,适用于基本的进程间数据传输。
- 低开销:在同一主机上的进程间通信,管道的开销相对较低。
- 内存共享:数据通过内核缓冲区传递,不需要手动分配和管理共享内存。
缺点:
- 单向性:匿名管道是单向的;虽然命名管道可以实现双向通信,但通常在使用中仍然是单向的。
- 阻塞:读操作会阻塞直到有数据可读;写操作会阻塞直到管道有足够的空间存储数据。
- 数据流:不支持随机访问,只能顺序读取。
适用场景:
- 简单的进程间通信,特别是父子进程之间的数据传输。
- 基于管道符(
|
)的 Unix 命令行数据流处理。