由于指针 (C),流水线理念不起作用

Pipeline idea not working due to pointers (C)

前段时间我在做一个小程序,我想把它缩短。

这个小程序是关于一个线程创建多个 child 的线程,这些 child 将使用管道按顺序将其标准 output/input 重定向到另一个,除了最后一个 child,谁不会' t 重定向它的标准输出,像这样。

Parent pipe  child1   pipe   child2  pipe   last child
       __             __             __
O-----|__|-----O-----|__|-----O-----|__|-----O -> Stdout

我第一次面对这段代码,我做了一个维度为[n_child][2]的矩阵,并从那个矩阵的每个位置做了一个管道,所以很容易连接每个需要时通过管道传输到每个 child。但现在我只想用 2 个管道尝试它,"playing" 继承。

也许我没有很好地解释自己,所以我认为用我的代码可以更好地理解所有内容,所以我们开始吧。

piping_function(int number_of_child){

    int i;
    int olddesc[2];
    int newdesc[2]; //Here I create the descriptors of the pipes I'll use
    int *olddir;
    int *newdir;
    if(pipe(olddesc)<0 || pipe(newdesc) < 0){  //I create the pipes
        //Error 
    }
    olddir = olddesc;
    newdir = newdesc; //And attach the directions to the array's direction (we will see later why)
    for(i = 0; i < number_of_child; i++){
        chaddr[i] = fork();
        switch(chaddr[i]){
            case -1:
                //Error trace
            case 0:
                dup2(olddesc[0],0); //Here I redirect the pipe who connect the previous child's pipe to the standard input
                if(i != number_of_child - 1)
                    dup2(newdesc[1],1); //And here, except from the last child, I redirect the standard output to the pipe who will connect to the standard input of the next child
                close(olddesc[0]);
                close(newdesc[1]); //I close the descriptors I don't need
                //Several child operations with standard input-output (end up returning 0/1 after the pipeline is connected, so no child will create any child)
            default:
                if(i == 0)
                    dup2(olddesc[1], 1); //I want the standard output of the principal proccess only on the first pipe
                olddir = newdir; //Here I would want the direction of the "old" pipe to be the direction of the "new" pipe, in order to achieve the pipeline
                if(pipe(newdesc)<0)
                    //Error
                break;
        }//End of switch
    }//End of for
    close(olddesc[0]);close(olddesc[1]);close(newdesc[0]);close(newdesc[1]); //I don't need these descriptors anymore, as they must be redirected to the standard's input/output of the process they need.
}//End of function

嗯,这是我的代码。我想我可以看到我正在做的错误,当我让 olddir 成为 newdir 并创建管道时,我正在做 olddir 也是那个新管道,对吗?那么我的问题来了:

有什么方法可以实现这种改变吗?我的意思是,我想要的是将 olddir(谁是 olddesc 的地址,对吗?所以如果我更改该地址,olddesc 的地址也会更改,对吗?)等于 newdir,以便继续我之前创建的管道重定向 "next" child 的标准输出,但我也希望 newdir 成为一个新管道。

我真的不知道我的解释是否正确,我不是母语人士,用其他语言解释这些想法有点困难。随时纠正任何语法错误,我将不胜感激,并提出有关代码的任何问题,因为我可能没有给出我想要的观点。

谢谢。

好吧,我终于做到了,但是改变了观点,不使用任何地址覆盖,只玩迭代,以便始终保持两个管道之一的记录。我并没有真正解决地址问题,但它确实有效,我很满意。

piping_function(int number_of_child){

    int i;
    int olddesc[2];
    int newdesc[2]; //Here I create the descriptors of the pipes I'll use

    //Now we'll start from the last pipe, so we can connect the parent to the first one and not connect the last child's output.
    for(i = number_of_child - 1; i >= 0; i--){
        //Instead of changing addresses, I'll play with the "i"
        if(i%2==0){
            close(newdesc[0]); //We close the last descriptors 
            close(newdesc[1]);
            pipe(newdesc); //And create a new pipe!
        }
        else{
            close(olddesc[0]);
            close(olddesc[1]);
            pipe(oldesc);
        }
        chaddr[i] = fork();
        switch(chaddr[i]){
            case -1:
                //Error trace
            case 0:
                if(i%2==0){
                    dup2(newdesc[0],0); //Here I redirect the pipe who connect the previous child's pipe to the standard input
                    if(i != number_of_child - 1)
                        dup2(olddesc[1],1); //And here, except from the last child, I redirect the standard output to the pipe who will connect to the standard input of the next child
                    close(newdesc[1]);
                    close(olddesc[0]); //I close the descriptors I don't need    
                }
                else{
                    dup2(olddesc[0],0); //Here I redirect the pipe who connect the previous child's pipe to the standard input
                    if(i != number_of_child - 1)
                        dup2(newdesc[1],1); //And here, except from the last child, I redirect the standard output to the pipe who will connect to the standard input of the next child
                    close(olddesc[1]);
                    close(newdesc[0]); //I close the descriptors I don't need
                }
                //Several child operations with standard input-output (end up exiting 0/1 after the pipeline is connected, so no child will create any child)
            default:
                if(i == 0)
                    dup2(newdesc[1], 1); //I want the standard output of the principal proccess only on the first pipe
                break;
        }//End of switch
    }//End of for
    close(olddesc[0]);close(olddesc[1]);close(newdesc[0]);close(newdesc[1]); //I don't need these descriptors anymore, as they must be redirected to the standard's input/output of the process they need.
}//End of function

*编辑:

我认为总是关闭描述符是不好的,即使没有创建任何东西,我看到我在这段代码中以这种方式保留了它们,但为了使其正常工作,我们应该只关闭描述符创建时,每次关闭时都需要一个 if。