C 管道不';不要用叉子循环工作
工作原理:父级创建一个子级,执行第一个命令并将输出重定向到管道,然后第二个子级将标准输入重定向到该管道。C 管道不';不要用叉子循环工作,c,pipe,fork,C,Pipe,Fork,工作原理:父级创建一个子级,执行第一个命令并将输出重定向到管道,然后第二个子级将标准输入重定向到该管道。 我的问题是:当第二个孩子试图从管道中读取数据时,它会一直等待 (我确实需要一个循环,因为在我的实际程序中,我不知道有多少命令,所以它只是一个简单的版本) #包括 #包括 #包括 #包括 int main(int argc,字符**argv){ int-fd[2]; 管道(fd); 对于(int i=0;i
我的问题是:当第二个孩子试图从管道中读取数据时,它会一直等待
(我确实需要一个循环,因为在我的实际程序中,我不知道有多少命令,所以它只是一个简单的版本)
#包括
#包括
#包括
#包括
int main(int argc,字符**argv){
int-fd[2];
管道(fd);
对于(int i=0;i<2;i++){
如果(fork()==0){
printf(“\n操作%d\n”,i);
如果(i==0){
dup2(fd[1],1);
关闭(fd[0]);
关闭(fd[1]);
printf(“\n执行前%s\n”,argv[1]);
execlp(argv[1],argv[1],NULL);
}
else如果(i==1){
dup2(fd[0],0);
关闭(fd[0]);
关闭(fd[1]);
printf(“\n执行前%s\n”,argv[2]);
execlp(argv[2],argv[2],NULL);
}
出口(0);
}
等待(空);
}
返回(0);
}
除了无法检查函数调用的返回值和处理这些返回值可能指示的错误之外,您的代码看起来相当合理。然而,我确实看到两个问题:
cat
、grep
或sed
,那么该进程将永远等待写入端关闭,因为主进程直到该子进程终止才会退出(因为wait()
)总的来说,管道通常只在两个端点之间提供通信。在这种常见情况下,重要的是在没有不必要延迟的情况下启动读写器,并确保管道端上的所有句柄在所有进程中都是关闭的,除了一个进程的一个线程中有一个读取端副本,另一个线程或不同进程中有一个写入端副本。在像您这样的情况下,避免不必要的延迟包括在两个(所有)子进程都启动之前,不要对任何子进程执行
wait()
ing操作。如果您按照应该的方式检查函数调用的返回值,那么您将知道故障发生的位置,如果确实存在任何实际故障。第一个孩子在“dup2(fd[1],1)”之后死亡,但我不明白为什么。dup2
的返回值是什么?我倾向于认为第一个孩子要么在execlp()
处失败,要么执行的程序挂起或阻塞,或者确实是执行程序运行到完成并终止。请特别注意,其printf()
的输出将进入管道。您可以fprintf()
到stderr
来避免这种情况。但是,如果任何函数调用失败,您可以从它们的返回值中知道它。对于这些特定功能,您还可以根据errno
,确定故障的性质,通过peror()
函数(顺便说一句,该函数将其输出发送到stderr
,而不是stdout
)可以方便地获得相关反馈。
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/wait.h>
int main(int argc, char**argv) {
int fd[2];
pipe(fd);
for(int i = 0; i < 2; i++) {
if (fork() == 0) {
printf("\nloop %d\n", i);
if (i == 0) {
dup2(fd[1], 1);
close(fd[0]);
close(fd[1]);
printf("\nbefore exec %s\n", argv[1]);
execlp(argv[1], argv[1], NULL);
}
else if(i == 1) {
dup2(fd[0], 0);
close(fd[0]);
close(fd[1]);
printf("\nbefore exec %s\n", argv[2]);
execlp(argv[2], argv[2], NULL);
}
exit(0);
}
wait(NULL);
}
return(0);
}