質問

I'm trying to send data between two pipes, that will go from parent->child->parent->child etc and so on until I exit the loop. Right now I'm trying to just pass an integer and increment it for each read done on it. At the moment it seems like each process is only incrementing it's own value and it's read component isn't working correctly. Are my pipes setup wrong?

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>

#define BUFFER_SIZE 25
#define READ  0
#define WRITE 1

int main(void)
{
  pid_t pid;
  //open two pipes, one for each direction
  int mypipefd[2];
  int mypipefd2[2];

  /* create the pipe */
  if (pipe(mypipefd) == -1 || pipe(mypipefd2) == -1) {
    fprintf(stderr,"Pipe failed");
    return 1;
  }

  /* now fork a child process */
  pid = fork();

  if (pid < 0) {
    fprintf(stderr, "Fork failed");
    return 1;
  }


  if (pid > 0) {  /* parent process */
    int parentVal = 0;
    while(1) {
      close(mypipefd[READ]);      //close read end, write and then close write end
      parentVal++;
      write(mypipefd[WRITE],&parentVal,sizeof(parentVal));
      printf("Parent: writes value : %d\n", parentVal);
      close(mypipefd[WRITE]);
      close(mypipefd2[WRITE]);        //close write end, read, and then close read end
      read(mypipefd2[READ],&parentVal,sizeof(parentVal));
      printf("Parent: reads value : %d\n", parentVal);
      close(mypipefd2[READ]);
    }
  }
  else { /* child process */
      int childVal = 0;
      while(1) {
      close(mypipefd[WRITE]);
      read(mypipefd[READ],&childVal,sizeof(childVal));
      printf("child: read value : %d\n", childVal);
      childVal++;
      close(mypipefd[READ]);
      close(mypipefd2[READ]);       //close read end, write and then close write end
      write(mypipefd2[WRITE],&childVal,sizeof(childVal));
      printf("child: write value : %d\n",childVal);
      close(mypipefd2[WRITE]);
    }
  }
}
役に立ちましたか?

解決 2

Your problem is that you're too enthusiastic about closing file descriptors. (That's a pleasant change from the usual; more often people don't close enough file descriptors.)

Each of the processes should close the ends of the pipes it is not going to use, but should do that before the loop. It should not close the pipes it is reading from or writing to if you want to iterate more than once. Those closes should be after the loop (and could be left out altogether since the program will terminate once the loop terminates, though it is generally better to explicitly close what you explicitly open). You should probably make sure that the loop does terminate (e.g. when the count reaches 1000).

他のヒント

In addition to what Jonathan Leffler said, I want to say that you should add checks to make sure that when read fails, you deal with the condition gracefully.

  if (pid > 0) {  /* parent process */
      int parentVal = 0;
      close(mypipefd[READ]);      // The parent is not going to read from the first pipe.
                                  // Close the read end of the pipe.
      close(mypipefd2[WRITE]);    // The parent is not going to write to the second pipe.
                                  // Close the write end of the pipe.
      while(1) {
          parentVal++;
          write(mypipefd[WRITE],&parentVal,sizeof(parentVal));
          printf("Parent: writes value : %d\n", parentVal);

          // If the chld closes the write end of the second pipe,
          // break out of the loop.
          if ( read(mypipefd2[READ],&parentVal,sizeof(parentVal)) > 0 )
          {
             printf("Parent: reads value : %d\n", parentVal);
          }
          else
          {
             break;
          }
      }

      close(mypipefd[WRITE]);    // Close the write end of the first pipe
      close(mypipefd2[READ]);    // Close the read end of the second pipe
  }
  else { /* child process */
      int childVal = 0;
      close(mypipefd[WRITE]);    // The child is not going to write to the first pipe.
                                 // Close the write end of the pipe.
      close(mypipefd2[READ]);    // The child is not going to read from the second pipe.
                                 // Close the read end of the pipe.
      while(1) {

          // If the parent closes the write end of the first pipe,
          // break out of the loop.
          if ( read(mypipefd[READ],&childVal,sizeof(childVal)) > 0 )
          {
             printf("child: read value : %d\n", childVal);
          }
          else
          {
             break;
          }

          childVal++;
          write(mypipefd2[WRITE],&childVal,sizeof(childVal));
          printf("child: write value : %d\n",childVal);
      }
      close(mypipefd[READ]);     // Close the read end of the first pipe
      close(mypipefd2[WRITE]);   // Close the write end of the second pipe
  }
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top