我正在做一个小程序,我不得不做了一段时间前,我想缩短它。
这个小程序是关于一个线程创建几个子线程,这些子线程按照顺序将其标准输出/输入重定向到另一个线程,除了最后一个子线程,后者不会像这样重定向其标准输出。

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

当我第一次面对这段代码时,我制作了一个维度为[núchild][2]的矩阵,并从该矩阵的每个位置制作了一个管道,因此在需要时很容易将每个管道连接到每个孩子。但现在我只想用两根管子,用继承来“玩”。
也许我并没有很好地解释自己,所以我想用我的代码可以更好地理解所有事情,所以我们开始吧。
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”子级的标准输出,但是我也希望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。

10-04 21:58