我正在创建各种流程(准确地说是3个)并让它们做不同的事情。 到现在为止还挺好。我想在父母等待,直到所有孩子都完成。我玩了很多选项(比如下面列出的那个),但是父母等待但是我必须按回车键才能返回shell(意味着某个孩子在父母之后完成了吗?)或者父母永远不会回到贝壳。有任何想法吗?指向哪里寻求更多帮助?感谢
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#define READ_END 0
#define WRITE_END 1
int main (int argc, char **argv)
{
pid_t pid;
int fd[2];
int fd2[2];
pipe(fd);
pipe(fd2);
for (int i=0; i<3; i++) {
pid=fork();
if (pid==0 && i==0) {
//never uses fd2, so close both descriptors
close(fd2[READ_END]);
close(fd2[WRITE_END]);
printf("i'm the child used for ls \n");
close(fd[READ_END]); /*close read end since I don't need it */
dup2(fd[WRITE_END], STDOUT_FILENO);
close(fd[WRITE_END]);
execlp("ls", "ls", "-hal", NULL);
break; /*exit for loop to end child's code */
}
else if (pid==0 && i==1) {
printf("i'm in the second child, which will be used to run grep\n");
close(fd[WRITE_END]);
dup2(fd[READ_END], STDIN_FILENO);
close(fd[READ_END]);
close(fd2[READ_END]);
dup2(fd2[WRITE_END], STDOUT_FILENO);
close(fd2[WRITE_END]);
execlp("grep", "grep","p",NULL);
break;
}
else if (pid==0 && i==2) {
//never uses fd so close both descriptors
close(fd[READ_END]);
close(fd[WRITE_END]);
printf("i'm in the original process which will be replaced with wc\n");
close(fd2[WRITE_END]);
dup2(fd2[READ_END], STDIN_FILENO);
close(fd2[READ_END]);
printf("going to exec wc\n");
execlp("wc","wc","-w",NULL);
break;
}
else {
//do parenty things
}
}
wait(NULL);
while (1){
wait(NULL);
if(errno== ECHILD) {
printf("all children ended\n");
break;
}
}
close(fd[READ_END]);
close(fd[WRITE_END]);
close(fd2[READ_END]);
close(fd2[WRITE_END]);
return 0;
}
答案 0 :(得分:7)
grep
和wc
永不退出。
为什么呢?他们从未在stdin上收到过EOF。
为什么呢?因为,即使ls
已退出并关闭pipe(fd)
的写入结束,主进程仍然会将pipe(fd)
的写入结束打开,因此pipe(fd)
的读取结束是仍在等待更多数据。类似的事情适用于fd2
:即使退出grep
,wc
也不会在stdin上获得EOF。
解决方案:close
等待之前主进程中的所有管道fds。