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

我正在编写一个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); } 

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

旧的generatePipesfunction:

 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); } 

新function:

 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]);