由于指针 (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。
前段时间我在做一个小程序,我想把它缩短。
这个小程序是关于一个线程创建多个 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。