Childs无法从管道获取任何值(父进程)

时间:2013-02-14 21:36:01

标签: c pipe

#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一样,我没有看到从父进程传入的字符串。

任何人都知道为什么?非常感谢你的帮助。

1 个答案:

答案 0 :(得分:5)

在fork之后在父进程中创建管道。这不起作用:孩子既不会看到父对fd数组的写入结果,也不会继承管道的文件描述符。

要解决的第一件事是:在分叉之前创建一个pipe。有许多警告,例如如果父母正在写作并且孩子正在阅读,那么孩子应该close继承一侧的管道,以便能够检测到EOF。