我可以使用管道作为在父级读取并在子级写入的方式吗?

时间:2018-12-16 23:52:46

标签: c pipe parent-child

我现在正在学习如何正确使用管道。我找到了仅用于在父级中写入和在子级中读取的示例,但是我想知道如何逆转它。我这样尝试过:

#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>

int main(){

  int  p1[2], p2[2];
  char original[]="This is a string\n ";

  pid_t child2;
  pid_t child=fork();

  if (child>0)
  {
    child2 = fork();
    if(child2>0){
      wait();
      printf("I'm the parrent.\n");

      close(p1[1]);
      close(p2[1]);

      printf("Parrent read p1:\n");
      if (read(p1[0], original, sizeof(original)) == -1)
        perror("read() error in parent p1");
      else printf("parent read '%s' from pipe 1\n", original);

      printf("Parrent read p2:\n");
      if (read(p2[0], original, sizeof(original)) == -1)
        perror("read() error in parent p2");
      else printf("parent read '%s' from pipe 2\n", original);
    }
    else{
      printf("Child2 \n");
      pipe(p2);
      close(p2[0]);
      if (write(p2[1], original, sizeof(original)+1) == -1)
        perror("write() error in child2");
      //close(p2[1]);
    }
  }
  else
  {
    printf("Child1 \n");

    pipe(p1);
    close(p1[0]);
    if (write(p1[1], original, sizeof(original)+1) == -1)
      perror("write() error in child1");
    //close(p1[1]);
  }
  return 0;
}

但是这种方式给我在阅读父母时出现的错误。 read() error in parent p1: Bad file descriptor两次,分别在p1p2。那么,我可以这样做吗?还是这只是一些小错误?

1 个答案:

答案 0 :(得分:1)

如前所述,您只需要反转索引即可关闭管道和进行读/写。

您的代码几乎正确。有两件事是错误的:在父级上,您先关闭管道,然后调用pipe():反之亦然:首先创建两个管道,然后关闭相应的元素,全部位于父级中。

第二,您应该在设置管道之后调用wait,否则它将不起作用。猜测您想等待所有应该呼叫wait(NULL)的孩子。我不知道您对wait()的意思。

完整代码:

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>

int main(){

  int  p1[2], p2[2];
  char original[]="This is a string\n ";

  pid_t child2;
  pid_t child=fork();

  if (child>0)
  {
    child2 = fork();
    if(child2>0){

      printf("I'm the parrent.\n");
      pipe(p1); //ADDED
      pipe(p2); //ADDED
      close(p1[1]);
      close(p2[1]);
      wait(NULL); //DON'T GET IT WHY? if u want to wait all children,
      //wait after setting the pipes.
      printf("Parrent read p1:\n");
      if (read(p1[0], original, sizeof(original)) == -1)
        perror("read() error in parent p1");
      else printf("parent read '%s' from pipe 1\n", original);

      printf("Parrent read p2:\n");
      if (read(p2[0], original, sizeof(original)) == -1)
        perror("read() error in parent p2");
      else printf("parent read '%s' from pipe 2\n", original);
    }
    else{
      printf("Child2 \n");
      //pipe(p2); ERROR HERE
      close(p2[0]);
      if (write(p2[1], original, sizeof(original)+1) == -1)
        perror("write() error in child2");
      //close(p2[1]);
    }
  }
}