使用pipe()在子进程和父进程之间进行管道通信

时间:2016-03-15 16:07:59

标签: c parent-child pipeline

我正在尝试使用pipe()建立一个管道,以在子进程和父进程之间进行通信。我在stackoverflow上读了一些帖子,有些使用了dup()和dup2()函数。有人可以解释这种情况下这些功能的用途吗?

2 个答案:

答案 0 :(得分:0)

您可以使用dup2分别重定向子进程和父进程的stdin和stdout,以通过与使用指令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

答案 1 :(得分:0)

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);
    }
}