2013-02-14 141 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