我正在为我的 CS 类编写一个 shell,该项目的一部分涉及在用户传入“&”字符时在后台运行一个进程。
如果一个进程在前台运行,我只需execvp
进程并且它仍然在终端的控制下,因为它在前台。但是,如果它是一个后台进程,我必须在开始执行该进程后将控制权返回到我的主 shell。我知道系统调用 tcsetpgrp(pid_t)
将作为参数传入的进程放在前台,但我不太明白如何使用它。
如果它是后台进程,我应该在 execvp
之后调用 tcsetpgrp
吗?如果是这样,我是否可以通过调用 getpid
获取我的 shell 的 pid?
最佳答案
tcsetpgrp()
适用于进程组,而不是单个进程。你想要做的是这样的:
当你创建一个新的管道时,调用
setpgid()
将管道的所有成员放入一个新的进程组中(以管道中第一个进程的PID作为PGID)。 (管道是您的 shell 在看到类似ls | grep foo | wc -l
的请求时启动的一系列进程 - 最简单的管道中只有一个进程)。通常,在调用exec()
之前,您会从管道中的第一个进程调用setpgid(0, 0)
。使用
tcsetpgrp()
来管理哪个进程组在前台。如果您将一个进程组从前台移动到后台,您可以将 shell 自己的进程组设置为前台进程组 - 您可以在 shell 中使用getpgid(0)
获取它。当 shell 在后台时,它应该使用阻塞
waitpid()
调用来等待子进程退出,而不是显示提示。一旦前台管道中的每个进程都退出,它应该再次将自己放回前台(并显示提示)。当 shell 在前台时,它应该调用带有
WNOHANG
和WUNTRACED
标志的waitpid()
来检查显示提示之前子进程的状态 - 这将在它们停止或退出时通知您,并让您通知用户。
关于c - 将进程发送到后台并将控制权返回到我的 shell,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10779020/