Unix管道(|)和C语言中使用“pipe(int pipefd[2])”创建的管道是否相同?

8
Unix管道(|)将一个进程的输出送到另一个进程,而使用C语言中的“pipe(int pipefd[2])”创建的管道用于进程间通信,它们是否相同?
3个回答

6

Shell管道|是使用pipe(2)dup2(2)系统调用实现的。

参见Unix Pipes


5
它们并不完全相同,因为仅调用 pipe(2) 不能实现 shell 中 | 的等价功能。

pipe(2) 创建两个文件描述符(读取端和写入端)。但是,您需要做更多的工作才能实现 | 功能。

创建管道的典型序列如下:

1)使用 pipe(2) 创建一个读取端和一个写入端。

2)使用 fork() 创建一个子进程。

3)父进程和子进程使用 dup2() 复制文件描述符。

4)两个进程分别关闭管道的一端(每个进程不使用的一端)。

5)一个进程写入管道,另一个进程从管道读取。

考虑一个简单的示例来说明这一点。在此示例中,您将一个文件名作为参数传递,并且父进程通过子进程 "grep" 文件,而子进程则执行 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 

在命令行界面(也称为shell)上。

为什么会创建重复项?我们不能在不重复的情况下写入和读取数据吗? - Ps Akshay
1
在所有的父子进程通信中,并不是严格需要使用dup2()。父进程和子进程也可以直接进行通信。例如,父进程可以向管道的写入端write(2)数据,而子进程则可以从读取端read(2)数据。 - P.P
@PsAkshay 因为执行的 grep 和 cat 只从 0 和 1 读写,而不是 pipefd。 - ctrl-d

0

pipe(2)系统调用被shell用于通过|运算符进行管道传输。

|是shell的实现,它内部使用pipe()系统调用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接