gpt4 book ai didi

c - 管道和过程管理

转载 作者:太空宇宙 更新时间:2023-11-04 12:12:44 25 4
gpt4 key购买 nike

我正在研究用 C 语言实现的微型 shell(tsh)(这是一项作业)。作业的一部分属于 PIPING。我必须将一个命令的输出通过管道传递给另一个命令。例如:ls -l |排序

当我运行 shell 时,我在其上执行的每个命令都由它生成的子进程处理。 child 完成后返回结果。对于管道,我想先实现一个硬编码示例来检查它是如何工作的。我写了一个方法,部分有效。问题是当我运行管道命令时,子进程完成后,整个程序随之退出!显然我没有正确处理子进程信号(下面的方法代码)。

我的问题:

  • pipe() 的进程管理是如何工作的?如果我运行命令 ls -l | sort 它是否为 ls -l 创建了一个子进程,为 sort 创建了另一个进程?从我目前看到的管道示例来看,只创建了一个进程(fork())。

  • 当第二个命令(我们示例中的sort)被处理时,我如何获得它的进程 ID?

编辑:同样在运行这段代码时我得到了两次结果。不知道为什么会运行两次,里面没有循环。

这是我的代码:

pid_t pipeIt(void){
pid_t pid;
int pipefd[2];

if(pipe(pipefd)){
unix_error("pipe");
return -1;
}

if((pid = fork()) <0){
unix_error("fork");
return -1;
}
if(pid == 0){
close(pipefd[0]);
dup2(pipefd[1],1);
close(pipefd[1]);
if(execl("/bin/ls", "ls", (char *)NULL) < 0){
unix_error("/bin/ls");
return -1;
}// End of if command wasn't successful

}// End of pid == 0
else{
close(pipefd[1]);
dup2(pipefd[0],0);
close(pipefd[0]);
if(execl("/usr/bin/tr", "tr", "e", "f", (char *)NULL) < 0){
unix_error("/usr/bin/tr");
return -1;
}
}

return pid;

}// End of pipeIt

最佳答案

是的,shell 必须 fork 来执行每个子进程。请记住,当您调用 execve() 函数族之一时,它会用已执行的进程镜像替换当前进程镜像。如果它直接执行子进程,您的 shell 将无法继续处理更多命令,因为此后它不再存在(子进程除外)。

要修复它,只需在 pid == 0 分支中再次使用 fork(),然后在该子分支中执行 ls 命令。如果您不想异步执行管道,请记住为两个(所有)子进程使用 wait()

关于c - 管道和过程管理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48350893/

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