[英]piping two times using fork in C linux
我正在尝试重写一个执行ls | wc | wc之类的ac程序,我已经为ls | wc做过它,它可以正常工作,但是我不知道为什么我的程序在指示的行中停留在孩子身上。 请帮忙!
int main (void)
{
pid_t pid_fils, pid_pfils;
int fd[2], fd2[2];
if(pipe(fd)==-1 || pipe(fd2)==-1)
{
printf("pipe failed!");
return 1;
}
printf("program started\n");
pid_fils=fork();
if(pid_fils==0)
{
pid_pfils=fork();
if(pid_pfils==0)
{
//action3
printf("I am the grandson\n");
close(fd[0]);//close read side
dup2(fd[1],1);//connect write with stdout
close(fd[1]);//close write side
execlp("ls","ls",(char*)0);
//execvp("ls",argv3);
return 0;/*actions grandson*/
}
else
{
//action2
printf("I am the son\n");
wait();
printf("son, wait ok\n");
>close(fd[1]); //close read side
>dup2(fd[0],0); //connect write with stdin
>close(fd[0]); //close read side
///////pipe2////
> close(fd2[0]); //close read side
>dup2(fd2[1],1); //connect write with stdout/*it stops here -can't display "ok!"*/
printf("ok!\n");
>close(fd2[1]); //close write side
execlp("wc","wc",(char*)0);
printf("error exec returned!\n");
return 0;
}
}
else
{
///action1
printf("I am the parent\n");
wait();
printf("parent,wait ok\n");
close(fd2[1]); //close write side,
dup2(fd2[0],0); //connect read with stdin
close(fd2[0]); //close read side
execlp("wc","wc",(char*)0);
return 0;/*the parent*/
}
return 1;
}
确保关闭所有未使用的描述符。 在您的情况下,最简单的解决方案是将pipe(fd)的创建移到第一个if块中(在第一个子过程中)。 问题在于,只要任何进程都可以写入管道,读取器就不会获得EOF,因此也不会终止。
if(pipe(fd2)==-1)
{
printf("pipe failed!");
return 1;
}
printf("program started\n");
pid_fils=fork();
if(pid_fils==0)
{
if(pipe(fd)==-1)
{
printf("pipe failed!");
return 1;
}
pid_pfils=fork();
我还应该提到,您可能需要重新考虑等待电话。 不确定您打算对它们做什么,但是您不希望“ ls”过程阻塞输出,因为尚未启动阅读器。
dup2(fd2[1],1);
上一行将首先关闭描述符1处的文件,然后将解密器从fd2 [1]复制到1。
1是标准输出。 表示该调用关闭了stdout。
printf打印到stdout,这意味着printf打印到1,现在分配给管道fd2
因此,您可以进入管道,而不是在屏幕上。
尝试
//action2
printf("I am the son\n");
wait();
printf("son, wait ok\n");
close(fd[1]); //close read side
dup2(fd[0],0); //connect write with stdin
close(fd[0]); //close read side
///////pipe2////
int my_terminal_out = dup(1);
close(fd2[0]); //close read side
dup2(fd2[1],1); //connect write with stdout/*it stops here -can't display "ok!"*/
fprintf(my_terminal_out, "ok!\n");
close(fd2[1]); //close write side
未经测试。 同样,您应该测试代码的其余部分是否存在类似的错误操作。
+ DrC怎么说。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.