我正在尝试创建一个类似 shell 的程序。 编写了一个示例片段程序来查看 ls | 的执行情况厕所。
在示例程序中,主进程创建一个子进程来执行每个命令(使用 execvp)并使用管道传递输出。
但是当我执行程序时,第二个 fork() (pid2) 的 waitpid 被阻塞。 当 waitpid 存在时,程序不会继续进行。
如果我注释第二个waitpid,我会得到输出(子进程在后台运行,并在主程序退出后打印输出)
waitpid的使用有什么问题?为什么第一个 waitpid 工作但第二个 waitpid 不工作?
注意:1) parse 是一个库,它接受输入的输入并将每个命令作为包含参数和必要数据的链接列表返回。解析工作正常
int main(int argc, char *argv[], char *envp[])
{
Pipe p;
Cmd c;
pipe(lol1);
pipe(lol2);
pid_t pid,pid2;
int i,status,st;
char *host = "armadillo";
fflush(stdout);
printf("%s%% ", host);
p = parse();
c=p->head;
printf("1 \n");
pid=fork();
if(pid==0)
{
dup2(lol1[1],1);
close(lol1[0]);
execvp(c->args[0],c->args);
}
else
{
waitpid(pid,&status,0);
}
printf("2 \n");
c=c->next;
printf("%s \n",c->args[0]);
pid2=fork();
if(pid2==0)
{
dup2(lol1[0],0);
close(lol1[1]);
execvp(c->args[0],c->args);
}
else
{
printf("just before wait pid \n");
waitpid(pid2,&st,0);
close(lol1[0]);
close(lol1[1]);
}
}
最佳答案
问题出在我在第一个进程中尝试写入的管道上。 第一个过程结束后我没有关闭管道的写入端。
因此,当第二个进程尝试读取管道的读取端时,因为管道未关闭,它将不会接收到 EOF,因此仍在等待来自管道的输入。
关闭管道的写入端,即添加此行
close(lol1[1]);
pid2=fork();
解决了问题
关于c - 当子进程执行 execvp 时,waitpid 未收到退出状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26332195/