Могу ли я использовать трубу как для чтения у родителя, так и для записи у ребенка? - PullRequest
0 голосов
/ 17 декабря 2018

Я сейчас учусь правильно использовать трубы.Я нашел примеры только для записи в родительском и чтения в дочернем, но я хочу знать, как я могу сделать это наоборот.Я пытался так:

#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 оба раза, на p1, а также на p2.Итак, я могу сделать это так или нет?Или это просто какая-то банальная ошибка?

1 Ответ

0 голосов
/ 17 декабря 2018

Как уже говорилось, вам просто нужно инвертировать индексы для закрытия каналов и чтения / записи.

Ваш код был почти верен.Две вещи были неправильными: на родительском объекте вы сначала закрывали каналы и затем вызывали 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]);
    }
  }
}
...