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