【问题标题】:Sending a process to the background and returning control to my shell将进程发送到后台并将控制权返回给我的 shell
【发布时间】:2012-06-02 11:43:30
【问题描述】:

我正在为我的 CS 类编写一个 shell,如果用户传入了“&”字符,则该项目的一部分涉及在后台运行一个进程。

如果一个进程在前台运行,我只需execvp 该进程,它仍然控制着终端,因为它在前台。但是,如果它是后台进程,我必须在开始执行该进程后将控制权返回给我的主 shell。我知道系统调用tcsetpgrp(pid_t) 将作为参数传入的进程放在前台,但我不太明白如何使用它。

如果是后台进程,我应该在execvp 之后调用tcsetpgrp 吗?如果是这样,我可以通过调用getpid获取我的shell的pid吗?

【问题讨论】:

  • 让我们试试这个。在您最喜欢的终端中启动两个会话。在第一个中运行一个命令,比如说 cat,它在 fg 中。切换到其他会话,用ps找到cat的pid。使用 kill 向其发送信号 SIGSTOP。观察发生了什么并分享您的发现。

标签: c linux shell background-process process-group


【解决方案1】:

tcsetpgrp() 适用于进程组,而不是单个进程。你想做的是这样的:

  1. 创建新管道时,调用setpgid()将管道的所有成员放入一个新的进程组(以管道中第一个进程的PID作为PGID)。 (管道是您的外壳在看到ls | grep foo | wc -l 之类的请求时启动的一系列进程 - 最简单的管道中只有一个进程)。通常你会从管道中的第一个进程调用setpgid(0, 0),然后再调用exec()

  2. 使用tcsetpgrp() 管理哪个进程组在前台。如果您将一个进程组从前台移动到后台,您可以将 shell 自己的进程组设置为前台进程组 - 您可以在 shell 中使用getpgid(0) 来获取它。

  3. 当 shell 在后台时,它应该使用阻塞的waitpid() 调用来等待子进程退出而不是显示提示。一旦前台管道中的每个进程都退出,它应该再次将自己放回前台(并显示提示)。

  4. 1234563他们已经停止或退出,并让您通知用户。

【讨论】:

    【解决方案2】:

    如果您的 shell 使用& 启动一个进程以将其作为后台,$! shell 变量将包含子进程的 PID。然后您可以向该进程发送信号,或使用wait $! 等待它完成。

    【讨论】:

      【解决方案3】:

      您应该查看fork 以创建子进程。然后,在子进程中使用exec 来运行所需的命令。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-10-01
        • 2016-12-15
        • 2012-03-06
        • 1970-01-01
        • 2011-04-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多