子程序不会在C程序中死亡

时间:2013-02-10 01:22:54

标签: c fork pipe stdin wait

我正在编写一个C程序,它将STDIN的输入解析为单词,生成numsorts变量指定的多个排序进程,以循环方式将单词传递给每个排序进程,并发送输出STDOUT的种类。

如果指定的排序进程数为1,我的程序将按照需要工作并干净地退出,但如果排序进程数大于1,则排序子进程不会死,并且我的程序会等待它们。对我来说,最奇怪的部分是,如果我打开一个单独的终端窗口并杀死除1之外的所有孩子,最后一个孩子会立即自行死亡并且程序干净利落。

这是我的解析器代码(管道文件描述符存储在一个二维数组中):

void RRParser(int numsorts, int **outPipe){ //Round Robin parser
    int i;
    char word[MAX_WORD_LEN];

    //Close read end of pipes
    for(i = 0; i < numsorts; i++){
        closePipe(outPipe[i][0]);
    }

    //fdopen() all output pipes
    FILE *outputs[numsorts];
    for(i=0; i < numsorts; i++){
        outputs[i] = fdopen(outPipe[i][1], "w");
        if(outputs[i] == NULL)
            printf("Error: could not create output stream.\n");
    }

    //Distribute words to them
    i = 0;
    while(scanf("%[^,]%*c,", word) != EOF){
        strtoupper(word);
        fputs(word, outputs[i % numsorts]); //round robin
        fputs("\n", outputs[i % numsorts]); //sort needs newline
        i++;
    }

    //Flush the streams:
    for(i=0; i < numsorts; i++){
        if(fclose(outputs[i]) == EOF)
            printf("Error closing stream.\n");
    }
}

这是生成排序过程的代码(PukeAndExit()只打印出错误消息并退出):

int *spawnSorts(int numsorts, int **inPipe){
    //returns an array containing all the PIDs of the child processes
    //Spawn all the sort processes
    pid_t pid;
    int i; 
    int *processArray = (int *)malloc(sizeof(int) * numsorts);
    for(i = 0; i < numsorts; i++){ 
        switch(pid = fork()){
            case -1: //oops case
                    PukeAndExit("Forking error\n");
            case 0: //child case
                //Bind stdin to read end of pipe
                closePipe(inPipe[i][1]); //close write end of input pipe
                if(inPipe[i][0] != STDIN_FILENO){ //Defensive check
                    if(dup2(inPipe[i][0], STDIN_FILENO) == -1)
                        PukeAndExit("dup2 0");
                    closePipe(inPipe[i][0]); //Close duplicate pipe
                }
                execlp("sort", "sort", (char *)NULL);
               break;
            default: //parent case
                processArray[i] = pid;
        }
    }
    return processArray;
}

在main()的末尾,这是等待排序进程死的代码:

for(i=0; i<numsorts; i++){ //wait for child processes to die. 
    wait(NULL);
}

1 个答案:

答案 0 :(得分:0)

没关系,我明白了。该bug实际上是在我生成管道的函数中。一旦我切换到我的spawnSorts过程中创建管道,一切都有效。以前,我在一个单独的函数中生成一个管道数组。我不确定为什么现在这样有效但是确实如此。

旧的generatePipes函数:

int **generatePipesArray(int numpipes){ //returns a 2-dimensional array of pipes
        int **pipesArray = (int **) malloc(sizeof(int *) * (numpipes));
        int i;
        for(i = 0; i < numpipes; i++){
                pipesArray[i] = (int *) malloc(sizeof(int) * 2);
                createPipe(pipesArray[i]);
        }
        return(pipesArray);
}

新功能:

int **generatePipesArray(int numpipes){ //returns an empty 2-dimensional array
        int **pipesArray = (int **) malloc(sizeof(int *) * (numpipes));
        int i;
        for(i = 0; i < numpipes; i++){
                pipesArray[i] = (int *) malloc(sizeof(int) * 2);
                //not creating pipes here anymore
        }
        return(pipesArray);
}

添加到spawnSorts的代码:

int *spawnSorts(int numsorts, int **inPipe, int **outPipe){
//returns an array containing all the PIDs of the child processes
//Spawn all the sort processes
pid_t pid;
int i; 
int *processArray = (int *)malloc(sizeof(int) * numsorts);
for(i = 0; i < numsorts; i++){
     //new code here:
    createPipe(inPipe[i]);