【问题标题】:Are unix pipe (|) and pipe we create using "pipe(int pipefd[2])" in c the same?unix管道(|)和我们在c中使用“pipe(int pipefd [2])”创建的管道是否相同?
【发布时间】:2015-12-14 13:37:32
【问题描述】:

将一个进程的输出通过管道传输到另一个进程的 unix 管道 (|) 与我们在 c 中使用“pipe(int pipefd[2])”创建的用于进程间通信的管道是否相同?

【问题讨论】:

    标签: c unix pipe


    【解决方案1】:

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

    Unix Pipes

    【讨论】:

      【解决方案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) 来自读取端。
      • @PsAkshay 因为执行的 grep 和 cat 只能从 0 和 1 读取/写入,而不是 pipefd。
      【解决方案3】:

      shell 使用 pipe(2) 系统调用与 | 运算符进行管道连接

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-04-25
        • 2014-11-24
        • 2014-05-31
        • 1970-01-01
        • 1970-01-01
        • 2010-12-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多