子进程不会在C程序中死去 [英] Child processes won't die in C program

查看:124
本文介绍了子进程不会在C程序中死去的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写解析输入从STDIN成字C程序,生成许多通过向每个排序过程的numsorts变量,管,可在一个循环方式词语指定的排序过程,并发送输出的种类到标准输出。

我的程序工作根据需要和完全退出,如果指定的排序进程数为1,但如果排序进程数大于1的排序子进程不会死,我的程序卡住等着他们。这样做的部分奇怪的,对我来说,如果我打开一个单独的终端窗口,杀死所有的孩子,除了1,最后一个孩子死于立即对自己和程序退出干净。

下面是解析器我code(管道文件描述符被存储在2维阵列):

 无效RRParser(INT numsorts,诠释** outPipe){//轮循分析器
    INT I;
    字符字[MAX_WORD_LEN]    //管道关闭读端
    对于(i = 0; I< numsorts;我++){
        closePipe(outPipe [I] [0]);
    }    // fdopen()中的所有输出管道
    FILE *输出[numsorts]
    对于(i = 0; I< numsorts;我++){
        输出[I] = fdopen(outPipe [I] [1],W);
        如果(输出[I] == NULL)
            的printf(错误:无法创建输出流\\ n);
    }    //分发话对他们
    I = 0;
    而(scanf函数(%[^,]%* C,字)!= EOF){
        strtoupper(字);
        的fputs(文字,输出[I%numsorts]); //循环赛
        的fputs(\\ n,输出[I%numsorts]); //排序需要换行
        我++;
    }    //冲洗流:
    对于(i = 0; I< numsorts;我++){
        如果(FCLOSE(输出[I])== EOF)
            的printf(错误收盘流\\ n);
    }
}

这里的code产生的排序过程(PukeAndExit()只打印出错误信息并退出):

 为int * spawnSorts(INT numsorts,诠释** inPipe){
    //返回包含子进程的所有的PID的数组
    //产卵所有的分类处理
    将为pid_t PID;
    INT I;
    为int * processArray =(INT *)malloc的(的sizeof(int)的* numsorts);
    对于(i = 0; I< numsorts;我++){
        开关(PID =叉()){
            案例-1://哎呀情况
                    PukeAndExit(分叉错误。\\ n);
            案件0://童案
                //绑定标准输入读取管道的终点
                closePipe(inPipe [I] [1]); //输入管道的关闭写端
                如果(inPipe [I] [0]!= STDIN_FILENO){//防御检查
                    如果(dup2(inPipe [I] [0],STDIN_FILENO)== - 1)
                        PukeAndExit(dup2 0);
                    closePipe(inPipe [I] [0]); //关闭重复管
                }
                execlp(排序,排序,(字符*)NULL);
               打破;
            默认://父案
                processArray [I] = PID;
        }
    }
    返回processArray;
}

目前的main()的结束,这里的code,它等待排序过程死亡:

 为(i = 0; I< numsorts;我++){//等待子进程死亡。
    等待(NULL);
}


解决方案

没关系,我理解了它。该错误实际上是在我所产生的管道的功能。当我切换到我的spaw​​nSorts过程中创造的管道,一切正常。 previously,我被产生管的一个单独的函数数组。我不知道为什么这个工程,但现在它的作用。

老generatePipes功能:

  INT ** generatePipesArray(INT numpipes){//返回管道的2维数组
        INT ** pipesArray =(INT **)的malloc(sizeof的为(int *)*(numpipes));
        INT I;
        对于(i = 0; I< numpipes;我++){
                pipesArray [I] =(INT *)malloc的(的sizeof(INT)* 2);
                createPipe(pipesArray [I]);
        }
        返回(pipesArray);
}

新功能:

  INT ** generatePipesArray(INT numpipes){//返回一个空的2维数组
        INT ** pipesArray =(INT **)的malloc(sizeof的为(int *)*(numpipes));
        INT I;
        对于(i = 0; I< numpipes;我++){
                pipesArray [I] =(INT *)malloc的(的sizeof(INT)* 2);
                //这里不是创造了管道
        }
        返回(pipesArray);
}

$ C $下加入spawnSorts:

 为int * spawnSorts(INT numsorts,INT ** inPipe,INT ** outPipe){
//返回包含子进程的所有的PID的数组
//产卵所有的分类处理
将为pid_t PID;
INT I;
为int * processArray =(INT *)malloc的(的sizeof(int)的* numsorts);
对于(i = 0; I< numsorts;我++){
     //新的code在这里:
    createPipe(inPipe [I]);

I'm writing a C program that parses input from STDIN into words, generates a number of sort processes specified by the numsorts variable, pipes the words in a round-robin fashion to each of the sort processes, and sends the output of the sorts to STDOUT.

My program works as desired and exits cleanly if the number of specified sort processes is 1, but the sort child processes don't die if the number of sort processes is greater than 1, and my program gets stuck waiting for them. The strangest part of this, to me, is that if I open up a separate terminal window and kill all of the children except 1, the last child immediately dies on its own and the program exits cleanly.

Here's my code for the parser (the pipe file descriptors are stored in a 2-dimensional array):

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

Here's the code that generates the sort processes (PukeAndExit() just prints out the error message and exits):

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

At the end of main(), here's the code that waits for the sort processes to die:

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

解决方案

Nevermind, I figured it out. The bug was actually in the function where I generated the pipes. As soon as I switched to creating the pipes in my spawnSorts process, everything worked. Previously, I was generating an array of pipes in a separate function. I'm not sure why this works now but it does.

Old generatePipes function:

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

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

Code added to 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]);

这篇关于子进程不会在C程序中死去的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆