gpt4 book ai didi

c - 在子进程中通过管道读取输入时循环无法终止

转载 作者:行者123 更新时间:2023-11-30 14:37:02 26 4
gpt4 key购买 nike

我正在使用 C 语言实现管道。我必须编写相当于 (grep -rF regex directory | tee output.txt | wc -l) 的 C 语言。然而,该代码无法继续执行超出 tee 等效项的操作。 (以下代码中标记的循环永远不会终止)。我不明白为什么循环没有终止以及为什么管道的输出没有传递到 newpipe 的输入。

当我删除 while 循环时,程序终止,输出为 0。

    int newpipe[2],p[2],pid;
char * argv_list1[] = {"grep","-rF","regex","directory",NULL};
char * argv_list2[] = {"wc","-l",NULL};
char *file="output.txt";
pid=fork();
if(pid==0){
int pid2=fork();
if(pid2==0){
close(p[0]);
dup2(p[1],1);
execvp("grep",argv_list1);
}
else{
wait(NULL);
int fd=open(file, O_RDWR | O_CREAT |O_TRUNC,0666);
close(newpipe[0]);
close(p[1]);
dup2(p[0], 0);
printf("pid2=%d\n",pid2);
dup2(newpipe[1],1);
char tmp;
while(read(p[0],&tmp,1)){
write(fd,&tmp,1);
write(1,&tmp,1);
}//This loop never terminates and the output comes on standard output
exit(1);
}
}
else{
wait(NULL);
close(newpipe[1]);
dup2(newpipe[0],0);
execvp("wc",argv_list2);
}

最佳答案

您的代码,如发布的,从不调用 pipeline() 来创建管道;所以这是一个问题,但在它出现之后,你还有更多的 fd 工作要做。

在你的第一个 child 中,即 exec() 的 grep 中,你正确地关闭了 p[0],并将写入结束 (p[1]) 复制到 STDOUT_FILENO (顺便说一句,a比 1) 更具描述性,但不要关闭 p[1]; dup2 就像一个副本而不是一个移动。这使它悬空。您可能会在最外层进程中创建 newpipe,因此您必须在此处关闭它的两端。

这同样适用于tee,它需要关闭其未使用的文件描述符,wc进程也是如此。

您需要删除等待,它们掩盖了一些 fd 处理错误。顺便说一句,请注意,在 tee 中,您将 p[0] 复制为 0,然后从 p[0] 读取。悬空管道不会生成 EOF。

围绕 pipeline() 和 fork() 的 fd 处理总是很麻烦。考虑每个进程中的每一个。

关于c - 在子进程中通过管道读取输入时循环无法终止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57657730/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com