我正在使用pipe fork和exec,为任何两个shell程序实现通用管道。我特意使用ls | grep来测试它。它工作,数据被复制到grep,grep搜索匹配,然后将它们输出到stdout。然而,之后该程序就会挂起。
这是我检测到管道时执行的代码。我fork,然后再次fork,因为我希望第一个fork的父进程在exec调用之后继续运行。我相信由于调试代码,在执行grep的exec()调用之后,没有发生任何事情。
if(pipeFlag == 1){
pipe(fd);
PID = fork();
if (PID == 0){//child process
fPID = fork();
if(fPID == 0){//child of child
printf("in child of child\n");
dup2(fd[1], 1);
execvp(command, argv);//needs error checking
printf("mysh: %s: command not found\n", argv[0]);
exit(EXIT_FAILURE);
}
if(fPID > 0){//parent of 2nd child
printf("in parent of 2nd child\n");
dup2(fd[0], 0);
execvp(command1, argv1);//needs error checking
printf("mysh: %s: command not found\n", argv[0]);
exit(EXIT_FAILURE);
}
if(PID == -1){
printf("ERROR:\n");
switch (errno){
case EAGAIN:
printf("Cannot fork process: System Process Limit Reached\n");
case ENOMEM:
printf("Cannot fork process: Out of memory\n");
}
return 1;
}
}
if(PID > 0){//parent
wait(PID, 0, 0);
printf("in outer parent\n");
}
if(PID == -1){
printf("ERROR:\n");
switch (errno){
case EAGAIN:
printf("Cannot fork process: System Process Limit Reached\n");
case ENOMEM:
printf("Cannot fork process: Out of memory\n");
}
return 1;
}
}
答案 0 :(得分:0)
以下是我解决问题的方法。我不确定它是否是一个永久的解决方案。我甚至不能100%确定我的理由是否有效以及之前的代码没有。我所做的只是将等待来自管道(grep)的输入的命令切换到父进程,并将命令写入管道(ls)到子进程。
我为什么这样做的原因是:我正在测试ls | grep,ls在grep的子进程设置之前已完成写入管道,因此从未关闭管道并且grep从未接收到EOF。通过改变它们的位置,grep已经准备就绪并且等待ls在设置进程ls的时候写入。我相信这是一个非常不完美的解决方案,所以对于将来读这篇文章的人,我希望你能提供更好的答案。如果我对其工作原理的推理是正确的,那么我可以想到一些条件,这可能仍然会陷入困境。
if(pipeFlag == 1){
pipe(fd);
PID = fork();
if (PID == 0){//child process
fPID = fork();
if(fPID == 0){//child of child
printf("in child of child\n");
dup2(fd[0], 0);
execvp(command1, argv1);//needs error checking
printf("mysh: %s: command not found\n", argv[0]);
exit(EXIT_FAILURE);
}
if(fPID > 0){//parent of 2nd child
printf("in parent of 2nd child\n");
dup2(fd[1], 1);
execvp(command, argv);//needs error checking
printf("mysh: %s: command not found\n", argv[0]);
exit(EXIT_FAILURE);
}
if(PID == -1){
printf("ERROR:\n");
switch (errno){
case EAGAIN:
printf("Cannot fork process: System Process Limit Reached\n");
case ENOMEM:
printf("Cannot fork process: Out of memory\n");
}
return 1;
}
}
if(PID > 0){//parent
wait(PID, 0, 0);
printf("in outer parent\n");
}
if(PID == -1){
printf("ERROR:\n");
switch (errno){
case EAGAIN:
printf("Cannot fork process: System Process Limit Reached\n");
case ENOMEM:
printf("Cannot fork process: Out of memory\n");
}
return 1;
}
}