pipe简要介绍

  • pipe是linux中用于创建管道(单向数据管道,a unidirectional data channel),可用于进程间的数据交互。

  • 函数声明为

    1
    2
    #include <unistd.h>
    int pipe(int pipefd[2]);

    当函数pipe成功返回时,数组pipefd分别被赋值为两个文件描述符,pipefd[0]为管道的读端口,pipefd[1]是管道的写端口。

  • 如果函数返回0则代表调用成功,返回-1代表调用失败。

样例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

int
main(int argc, char *argv[])
{
int pipefd[2];
pid_t cpid;
char buf;

if (argc != 2) {
fprintf(stderr, "Usage: %s <string>\n", argv[0]);
exit(EXIT_FAILURE);
}

if (pipe(pipefd) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
}

cpid = fork();
if (cpid == -1) {
perror("fork");
exit(EXIT_FAILURE);
}

if (cpid == 0) { /* Child reads from pipe */
close(pipefd[1]); /* Close unused write end */

while (read(pipefd[0], &buf, 1) > 0)
write(STDOUT_FILENO, &buf, 1);

write(STDOUT_FILENO, "\n", 1);
close(pipefd[0]);
_exit(EXIT_SUCCESS);

} else { /* Parent writes argv[1] to pipe */
close(pipefd[0]); /* Close unused read end */
write(pipefd[1], argv[1], strlen(argv[1]));
close(pipefd[1]); /* Reader will see EOF */
wait(NULL); /* Wait for child */
exit(EXIT_SUCCESS);
}
}

上述程序的功能是假借(这里的假就是借的意思)一个数据管道,使用fork系统调用创建子进程,在子进程中将命令行参数写入管道,然后在父进程中读取管道并标准输出,体现出的效果就是将命令行参数打印(注意规定了参数只有一个)。

下面给出该代码的一些使用案例(已编译为pipetest二进制文件)

1
2
3
4
$ ./pipetest CfLoveQzh
Usage: ./pipe_test <string>
$ ./pipetest CfLoveQzh
CfLoveQzh