2016-05-22 11 views
4

私はforkを使用して2人の子供を作成する必要があるこの割り当てを持っています。親はそれらの子供たちに手紙を送って番号を返さなければならない。通信はパイプを使用して行う必要があります。 私が理解できないことは、私のコードが子供に手紙を送ることを管理しているのに、何もしないだけです。最初は私がwaitpid()呼び出しのためだと思っていましたが、そうではないようです。何が私を困惑させるのは、子プロセスの1つで読み込みを停止し、乱数を送信するだけであれば、それ以外はすべて期待どおりに動作するということです。パイプで2人の子供から親にデータを送るにはどうしたらいいですか?

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

#define PIPE_1 0 // write to 1st child 
#define PIPE_2 1 // write to parent from 1st child 
#define PIPE_3 2 // write to 2nd child 
#define PIPE_4 3 // write to parent from 2nd child 

int main() 
{ 
    pid_t p1, p2; 
    int pipes[4][2]; 
    FILE *read[4], *write[4]; 

    int k; 
    for (k = 0; k < 4; k++){ 
     if (-1 == pipe(pipes[k])){ 
      perror("Error creating pipe"); 
      exit(k+1); 
     } 
     read[k] = fdopen(pipes[k][0], "r"); 
     write[k] = fdopen(pipes[k][1], "w"); 
    } 

    if (-1 == (p1 = fork())){ 
     perror("Error, failed to fork first child"); 
     exit(5); 
    } 

    if (p1 == 0){ 
     // 1st child 
     fclose(write[PIPE_1]); 
     int caseChange = 0; 
     char c; 
     while(fscanf(read[PIPE_1], "%c", &c) != EOF){ 
      if (c >= 97 && c <= 122){ 
        c -= 32; 
        caseChange++; 
      } 
      printf("[Process (%d)]: %c\n", getpid(), c); 
     } 
     fclose(read[PIPE_1]); 

     fclose(read[PIPE_2]); 
     fprintf(write[PIPE_2],"%d",caseChange); 
     fflush(write[PIPE_2]); 
     fclose(write[PIPE_2]); 
    } 
    else{ 
     if (-1 == (p2 = fork())){ 
      perror("Error, failed to fork second child"); 
      exit(6); 
     } 

     if (p2 == 0){ 
      // 2nd child 
      fclose(write[PIPE_3]); 
      int caseChange = 0; 
      char c; 
      while(fscanf(read[PIPE_3], "%c", &c) != EOF){ 
       if (c >= 97 && c <= 122){ 
        c -= 32; 
        caseChange++; 
       } 
       printf("[Process (%d)]: %c\n", getpid(), c); 
      } 
      fclose(read[PIPE_3]); 

      fclose(read[PIPE_4]); 
      fprintf(write[PIPE_4],"%d",caseChange); 
      fflush(write[PIPE_4]); 
      fclose(write[PIPE_4]); 
     } 
     else{ 
      // Parent 
      //char *string = (char*) malloc(100); 
      char string[100]; 
      scanf("%s", string); 
      int i; 

      int readCaseChange, caseChange = 0; 

      fclose(read[PIPE_1]); 
      for (i = 0; i < strlen(string); i+=2){ 
       fprintf(write[PIPE_1],"%c",string[i]); 
       fflush(write[PIPE_1]); 
      } 
      fclose(write[PIPE_1]); 

      fclose(read[PIPE_3]); 
      for (i = 1; i < strlen(string); i+=2){ 
       fprintf(write[PIPE_3],"%c",string[i]); 
       fflush(write[PIPE_3]); 
      } 
      fclose(write[PIPE_3]); 

      waitpid(p1, NULL, 0); 
      fclose(write[PIPE_2]); 
      fscanf(read[PIPE_2], "%d", &readCaseChange); 
      fclose(read[PIPE_2]); 
      caseChange += readCaseChange; 

      waitpid(p2, NULL, 0); 
      fclose(write[PIPE_4]); 
      fscanf(read[PIPE_4], "%d", &readCaseChange); 
      fclose(read[PIPE_4]); 
      caseChange += readCaseChange; 

      printf("%d\n", caseChange); 
      fflush(stdout); 
     } 
    } 
    return 0; 
} 

答えて

1

あなたは親プロセスのためにあなたはすべての子供には使用していないもの、特にライタ側を閉じたい:

// 1st child 
fclose(write[PIPE_1]); 
fclose(write[PIPE_3]); 

// 2nd child 
fclose(write[PIPE_1]); 
fclose(write[PIPE_3]); 

そうでない場合は、子プロセスがオープンライタ側を続けると、パイプが完全に閉じないようにして、子プロセスでEOFを取得しないようにします。あなたは部分的にこれをやっていましたが、2番目の子供が[PIPE_1]を開いていたので、PIPE_1は完全に閉じられませんでした。

関連する問題