我正在尝试写一个C程序,它可以执行类似于管道ls | wc | wc
的操作。我已经为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;
}
字符串
3条答案
按热度按时间uhry853o1#
确保关闭所有未使用的描述符。在您的情况下,最简单的解决方案是将管道(fd)的创建移动到第一个if块(在第一个子进程中)。问题是,只要任何进程都可能写入管道,读取器就不会被删除,因此不会终止。
字符串
我还应该提一下,你可能需要重新考虑等待调用。不确定你打算用它们做什么,但你不希望“ls”进程在输出时阻塞,因为阅读器还没有启动。
wbrvyc0a2#
字符串
上面一行将首先关闭描述符1处的文件,然后将描述符从fd2[1]复制到1。
1是stdout。意味着调用关闭了stdout。
printf打印到stdout,这意味着printf打印到1,它现在被分配给管道fd2
所以你的OK进入了管道而不是在屏幕上。
尝试
型
还没有测试。你应该测试你的代码的其余部分是否有类似的错误。
”DrC说。
mf98qq943#
扩展这个SO answer,我们可以创建一个额外的管道,fork另一个进程,并相应地连接管道。
字符串
编译并运行它:
型