gpt4 book ai didi

c - 管道和流程管理

转载 作者:行者123 更新时间:2023-12-02 20:21:37 25 4
gpt4 key购买 nike

我正在开发一个用 C 实现的小型 shell(tsh)(这是一项作业)。作业的一部分属于 PIPING。我必须将一个命令的输出通过管道传输到另一个命令。例如:ls -l | sort

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

我的问题:

  • 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/26874764/

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