【问题标题】:Pipeline Communication between Child Process and Parent Process using pipe()使用 pipe() 在子进程和父进程之间进行管道通信
【发布时间】:2016-03-15 16:07:59
【问题描述】:

我正在尝试使用 pipe() 设置管道以在子进程和父进程之间进行通信。我阅读了一些关于 stackoverflow 的帖子,其中一些使用了 dup() 和 dup2() 函数。有人可以解释一下这些函数在这种情况下的用途吗?

【问题讨论】:

    标签: c parent-child pipeline


    【解决方案1】:

    您可以使用dup2 分别重定向子进程和父进程的标准输入和标准输出,以通过与使用指令pipe 创建的文件描述符一起使用的管道发送消息。为了更具体地说明它的功能,这里有一个详细的例子来说明如何做到这一点。

    #include <unistd.h>
    #include <stdio.h>
    #define READ 0
    #define WRITE 1
    int main (int argc, char * argv [ ] )
    { 
        int fd[2];
        pipe(fd); // creating an unnamed pipe
        if (fork() !=0)
        { 
            close(fd[READ]); // Parent close the reading descriptor
            dup2(fd[WRITE], 1); // copy fd[WRITE]] in the descriptor 1 (stdout)
            close (fd[WRITE]); // closing the writing descriptor, not needed anymore because of stdout
            if(execlp(argv[1], argv[1], NULL) ==-1) // execute the program writer passed as an argument to myprog
                perror("error in execlp");
        }
        else // child process (reader)
        { 
            // closing unused writing descriptor
            close(fd[WRITE]);
            // copy fd[READ] in descriptor 0 (stdin)
            dup2(fd[READ],0);
            close (fd[READ]); // closing reading descriptor, not needed anymore because of stdin
            // execute reading command
            if(execlp(argv[2], argv[2], NULL) == -1) // Execute the reader passed as an argument to myprog
                perror("connect");
        }
        return 0 ;
    }
    

    这样,父进程通过标准输出发送的每条消息都会被重定向到子进程的标准输入。例如,当执行命令myprog who wc(上面显示的代码)时,它的行为就像在终端中执行who | wc一样。可以看到我的父进程who会通过标准输出向wc发送消息。

    因为这是dupdup2 之间的区别。你可以看看这个link

    【讨论】:

    • 为了清楚起见可以省略错误检查,但为什么要把它留在execlp?保持一致,并说明生产代码需要检查forkpipe等的返回值
    • 我会纠正这个以保持一致,但我的主要目标是向 OP 教授一些东西,即使他的问题没有要求任何代码。 你是对的,但我不会坚持并解释为什么生产代码中的 fork 和 pipe 需要进行错误检查。
    • 如果您需要将字符串消息从子级传递给父级,您会使用 write(pipeEnds1[1],str,strlen(str)) 吗?
    • @Varun 假设您的 pipeEnds1[1]... 是文件描述符的变量(或者如果我理解正确,您的管道结束),但您不需要 dup 或 @ 987654335@ 如果你这样做。您不需要 dupdup2 来编写 Mou 所述的流程。并假设 pipeEnds1[1] 将是您的编写器描述符,是的,您将在子进程中写入该文件描述符并从父进程的 pipeEnds1[0] 读取。如果这是您想知道的,请编辑您的问题。另外,如果您认为答案是否能回答您的问题,请点赞或解决。
    • 当管道已满并且我尝试写入它时,它给了我一个错误我可以进行系统调用以便将数据保存在缓冲区中直到管道有空间?
    【解决方案2】:

    pipe() 创建新的文件描述符,这意味着您可以像对文件、标准输入等进行写入和读取它们。

    dup2dup 是重命名文件描述符,例如将标准输出替换为程序

    要与子进程和父进程通信,实际上不需要dupdup2

    您可以改用 pipe() 给您的新文件描述符,并保持标准输入/输出打开

    这是一个简单的父子进程通信

    int main()
    {
      int fd[2];
      int pid;
    
      if (pipe(fd) == -1)
        return (1);
    
      pid = fork();
    
      if (pid == 0)
        {
          /* child process
           reading parent process */
          char rdbuff[10];
          close(fd[1]);
          read(fd[0], rdbuff, 10);
          printf("got: %s\n", rdbuff);
        }
      else if (pid > 0)
        {
          /* parent
           sending string to child process */
          close(fd[0]);
          write(fd[1], "sup!", 5);
        }
      else
        {
          /* error */
          return (1);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-27
      • 1970-01-01
      • 2011-12-22
      • 2020-04-09
      • 2011-10-16
      相关资源
      最近更新 更多