2017-03-03 75 views
2

問題:父節點將從鍵盤讀取一個整數,並使用管道將值發送給其子節點之一。孩子將會把這個價值和方塊傳給下一個孩子。另一個孩子將添加一個收到的值。然後這個孩子將這個值傳回給父母,並且父母將會打印到屏幕上。這將重複,直到EOF作爲輸入。在進程之間正確配管

坦率地說,這是一個實驗室練習,我認爲我已經把它放下了,但我並不清楚一些邏輯。對於我的代碼,預期的輸出將首次運行,但只是第一次。在第一次運行後給出的任何輸入都將導致沒有反應或不正確的行爲(例如將值傳遞給孩子並且什麼也沒有發生)。

 #include <fcntl.h> 
    #include <stdio.h> 
    #include <stdlib.h> 
    void square_plus1() 
    { 
    int fd[2]; 
    int fd2[2]; 
    int fd3[3]; 
    int value; 
    int myInt; 
    int status; 
    pid_t child1; 
    pid_t child2; 

    pipe(fd); 
    pipe(fd2); 
    pipe(fd3); 
    child1 = fork(); 
    child2 = fork(); 

    if(child1 == 0) 
    { 
     close(fd3[0]); 
     close(fd3[1]); 

     close(fd[1]); 
     close(fd2[0]); 

     read(fd[0],&value,sizeof(value)); 
     close(fd[0]); 
     printf("Child1(%d) received value: %d\n", getpid(), value); 
     value = value * value; 
     write(fd2[1],&value,sizeof(value)); 
     close(fd2[1]); 
     exit(0); 
    } 
    else if(child2 == 0) 
    { 
     close(fd[0]); 
     close(fd[1]); 

     close(fd2[1]); 
     close(fd3[0]); 

     read(fd2[0],&value,sizeof(value)); 
     printf("Child2(%d) received value: %d\n", getpid(), value); 
     close(fd2[0]); 
     value++; 
     write(fd3[1],&value,sizeof(value)); 
     close(fd3[1]); 
     exit(0); 
    } 
    else 
    { 
     while((scanf("%d", &value)) != EOF) 
     { 
      write(fd[1],&value, sizeof(value)); 
      printf("Parent(%d) sent value: %d\n", getpid(), value); 
      waitpid(child1,&status,0); 
      if(status == 0) 
      { 
      } 
      waitpid(child2,&status,0); 
      if(status == 0) 
      { 
      } 
      read(fd3[0],&value,sizeof(value)); 
      printf("New Value: %d\n",value); 
     } 

     waitpid(child1,&status,0); 
     if(status == 0) 
     { 
      printf("Child 1 finishes normally\n"); 
     } 
     waitpid(child2,&status,0); 
     if(status == 0) 
     { 
      printf("Child 2 finishes normally\n"); 
     } 
     close(fd2[0]); 
     close(fd2[1]); 
     close(fd[0]); 
     close(fd[1]); 
     close(fd3[1]); 
     close(fd3[0]); 
    } 
    } 
    int main(void) 
    { 
    square_plus1(); 
    return 0; 
    } 

我有點了解管道,但還不足以解決問題。任何幫助/引用非常感謝。

回答

0

首先,由於兩次連續的fork()調用,所以在這裏混合使用了四個進程。這就是你所擁有的

child1 = fork(); 
child2 = fork(); 

第一次分叉後,你有兩個進程的父母和孩子。現在當你做第二個分支時,父母和孩子都會分別添加一個子進程。所以你在這個時間點有四個進程。你可能想要把第二個分叉移到父進程(如果是child == 0))或者子進程(if(child!= 0)內部。另一個需要處理的事情是在處理第一個輸入之後你的子進程因此下一次處理不會發生在任何情況下,接下來你的管道需要適當的設置才能使它移動

假設fd1,fd2和fd3是成對的,下面是你應該做的(不完整的代碼,但只是爲了傳達圖片)

child1 = fork(); 
    if(child1 == 0) { 
      // 1st child 
      // .. code to close fds accordingly 
      while (1) { 
        read(fd1[0],&value,sizeof(value)); 
        printf("Child1(%d) received value: %d\n", getpid(), value); 
        value = value * value; 
        write(fd2[1],&value,sizeof(value)); 
      } 
      exit(0); 
    } else { 
      child2 = fork(); 
      if(child2 == 0) { 
        // 2nd child process 
        // .. code to close fds accordingly 
        while (1) { 
          read(fd2[0],&value,sizeof(value)); 
          printf("Child2(%d) received value: %d\n", getpid(), value); 
          value++; 
          write(fd3[1],&value,sizeof(value)); 
        } 
        exit(0); 
      } 
      // Parent process 
      // .. code to close fds accordingly 
      while((scanf("%d", &value)) != EOF) 
      { 
        write(fd1[1],&value, sizeof(value)); 
        printf("Parent(%d) sent value: %d\n", getpid(), value); 
        read(fd3[0],&value,sizeof(value)); 
        printf("New Value: %d\n",value); 
      } 

    } 
+0

很多這沒有意義。爲什麼我會有一個無休止的循環,將繼續讀管道。其次爲什麼是child2!= 0,不應該是child2 == 0.也運行此實現即使無限循環固定,也不會產生所需的動作。但是,我確實理解將第二個子進程移到父進程中。 – GreenSkies

+0

以上很多內容都來自問題中指定的代碼,除了重新組織之外。無盡的循環,因爲下面的句子在問題中要求「......這將重複,直到EOF作爲輸入..」,並在這裏「...工作的第一次,但只有第一次。第一次運行將導致沒有反應或不正確的行爲(......「關於孩子!= 0觀察是正確的,第二個孩子應該是孩子== 0,除此之外它工作,爲9並且它打印82,爲10它打印101,直到你退出。孩子退出是不是上述代碼的一部分 –

+0

是的,我想出來,但感謝您的反饋。 – GreenSkies