2013-02-14 152 views
0
#include <stdio.h> 
#include <string.h> 
#include <sys/time.h> 
#include <sys/wait.h> 
#include <signal.h> 
#include <fcntl.h> 
#include <unistd.h> 
#include <stdlib.h> 
//Functions Prototype 
void dadstuff(int [], int); 
void kidstuff(int,char*, int [3][2]); 

#define NUM 3; 
int main(int argc, char *argv[]) 
{ 
    int m = rand()%100 + 1; 
    int fd [3][2]; 
    char token[] = "GO_AHEAD\n"; 
    char readbuffer[80]; 
    //printf("%d\n",m); 
    if (argc != 2) /* argc should be 2 for correct execution */ 
    { 
     /* We print argv[0] assuming it is the program name */ 
     printf("usage: [filename]\n"); 
    }else 
    { 
     int val = NUM; 
     int i, dad, kidid[val]; 
     char *name = "dad"; 

     for(i =0; i<val; i++) 
     { 
      if(-1 == (dad = kidid[i] = fork())) 
      { 
       printf("Could not produce kid # %d\n", i+1); 
       //exit(99); 
      } 
      if(!dad) 
       break; 
     } 

     if(dad) 
     { 
      dadstuff(kidid,i); 
      pid_t pid; 
      int status; 

      for(i =0; i<val; i++) 
      { 
       if(-1 == pipe(fd[i])) 
       { 
        fprintf(stderr, "pipe(): Failed to create piple\n"); 
        exit(1); 
       } 
       printf("\nbefore"); 
       printf("\n"); 
       //close(fd[i][0]); //close up input side 
       write(fd[i][1], token, strlen(token)); 


       //Waiting for all child to ends before processing in parent 
       waitpid(kidid[i], &status, 0); 
       printf("\nChild%d, my id is: %d end with status %d\n", i+1, kidid[i],status); 
      } 
      printf("\nParent: Good bye!\n"); 
      printf("\n"); 
     } 
     else 
     { 
      kidstuff(i, argv[1], fd); 
      if(i==0) name = "child1"; 
      if(i==1) name = "child2"; 
      if(i==2) name = "child3"; 

      exit(m); 
     } 
    } 
    //return 0; 
} 
//Parent function 
void dadstuff(int kid[], int n) 
{ 
    printf("\nI am the father of the followings: "); 
    while (n != 0) 
    { 
     if(n == 1) 
      printf("and "); 
     printf("%d ", kid[--n]); 
     //printf("%d----", n); 
    } 
    printf("\n"); 
} 
//Child 1 to 3 function 
void child1(char *fileName) 
{ 
    //do something 
} 
void child2() 
{ 
    //do something 
} 
void child3(char *fileName) 
{ 
    //do something 
} 
void kidstuff(int i, char *fileName, int fd[3][2]) 
{ 
    //close(fd[i][1]); //close up output side 
    char readbuffer[80]; 
    int nbytes = 0; 

    printf("\nI am kid %d and my id is: %d\n", i+1, getpid()); 
    //child 1 
    if(i+1 == 1) 
    { 
     //HOW COME PIPE WASN'T RETURNING ANYTHING?? 
     nbytes = read(fd[i][0],readbuffer,sizeof(readbuffer)); 

     printf("\n"); 
     printf("buffer: %s", readbuffer); 

     while(readbuffer!="GO_AHEAD") 
     { 
      nbytes = read(fd[i][0],readbuffer,sizeof(readbuffer)); 
      printf("buffer: %s", readbuffer); 
      printf("\n"); 
      sleep(1); 
     } 
     child1(fileName); 
    } 

    //child 2 
    if(i+1 == 2) 
    { 
     child2(); 
    } 
    //child 3 
    if(i+1 == 3) 
    { 
     child3(fileName); 
    } 

} 

我想從父進程傳遞一個字符串到3個子進程。但由於某種原因,所有兒童進程都沒有從管道中獲取任何東西。我做錯了什麼嗎?就像當我在子函數中打印readbuffer時,我沒有看到從父進程傳入的字符串。孩子無法從管道獲得任何值(父進程)

有人知道爲什麼嗎?非常感謝你的幫助。

+2

等待 - 您正在創建流程,然後_then_管道? – 2013-02-14 21:47:17

回答

5

您在fork之後在父進程中創建管道。這是行不通的:孩子既沒有看到父母寫入fd數組的結果,也沒有繼承管道的文件描述符。

首先要解決的是:在分叉之前創建一個pipe。有一些警告,例如如果父母正在寫作並且孩子正在讀書,那麼孩子應該繼承close書寫一側的管道能夠檢測到EOF。

+0

令人驚歎!我無法相信我忘記了這一點。 – 2013-02-14 21:54:41