我正在尝试重写像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;
}
答案 0 :(得分:3)
确保关闭所有未使用的描述符。在您的情况下,最简单的解决方案是将管道(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”进程阻止输出,因为读者尚未启动。
答案 1 :(得分:1)
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说的话。