1

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

如果指定的排序进程数为 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);
}
4

1 回答 1

0

没关系,我想通了。该错误实际上是在我生成管道的函数中。一旦我切换到在我的 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]);
于 2013-02-10T19:03:12.377 回答