Send data between pipes in C with While loop


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?

我正在嘗試在兩個管道之間發送數據,這些數據將來自parent-> child-> parent-> child等,直到我退出循環。現在我正試圖傳遞一個整數,並為每次讀取增加它。目前似乎每個進程只是遞增它自己的值而且它的讀取組件無法正常工作。我的管道設置錯了嗎?

#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 个解决方案

#1


1  

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).

每個進程都應該關閉它不會使用的管道的末端,但是應該在循環之前執行。如果您想多次迭代,它不應該關閉它正在讀取或寫入的管道。那些關閉應該在循環之后(並且可以完全省略,因為一旦循環終止,程序將終止,盡管通常更好地明確地關閉你明確打開的東西)。您應該確保循環確實終止(例如,當計數達到1000時)。

#2


2  

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.

除了Jonathan Leffler所說的,我想說你應該添加檢查以確保當讀取失敗時,你會優雅地處理這個條件。

  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
  }

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com