【发布时间】:2015-12-14 13:37:32
【问题描述】:
将一个进程的输出通过管道传输到另一个进程的 unix 管道 (|) 与我们在 c 中使用“pipe(int pipefd[2])”创建的用于进程间通信的管道是否相同?
【问题讨论】:
将一个进程的输出通过管道传输到另一个进程的 unix 管道 (|) 与我们在 c 中使用“pipe(int pipefd[2])”创建的用于进程间通信的管道是否相同?
【问题讨论】:
Shell pipe | 是使用 pipe(2) 和 dup2(2) 系统调用实现的。
【讨论】:
在调用pipe(2)不足以实现shell的|的等效功能的意义上,它们并不完全相同。
pipe(2) 创建两个文件描述符(读端和写端)。但您需要做的不止这些,才能实现| 功能。
创建管道的典型顺序如下:
1) 使用pipe(2) 创建一个读端和一个写端。
2) 使用fork() 创建一个子进程。
3) 父子进程使用dup2()复制文件描述符。
4) 两个进程,各自关闭管道的一端(每个进程不使用的管道一端)。
5) 一个写入管道,另一个从管道读取。
考虑一个简单的例子来证明这一点。在此,您将文件名作为参数传递,父进程“greps”子进程的 cat 文件。
#include <stdio.h>
#include <unistd.h>
int main(int argc, char **argv)
{
int pipefd[2];
int pid;
char *cat_args[] = {"cat", argv[1], NULL};
char *grep_args[] = {"grep", "search_word", NULL};
pipe(pipefd);
pid = fork();
if (pid != 0)
{
dup2(pipefd[0], 0);
close(pipefd[1]);
execvp("grep", grep_args);
}
else
{
dup2(pipefd[1], 1);
close(pipefd[0]);
execvp("cat", cat_args);
}
}
这相当于做
cat file | grep search_word
在外壳上。
【讨论】:
dup2())。你的父母和孩子也可以直接交流。例如,父级可以write(2) 进入管道的写入端,子级可以read(2) 来自读取端。
shell 使用 pipe(2) 系统调用与 | 运算符进行管道连接
| 是shell 的实现,它内部使用pipe() 系统调用。
【讨论】: