唤醒进程后无法终止

唤醒进程后无法终止

我运行该程序yes并按Ctrl+Z来停止该进程。

之后,我通过执行将其唤醒kill -s 18 <pid>

此后,我无法再使用Ctrl+停止它Z或使用Ctrl+将其杀死C。这是为什么?

答案1

这都是关于 shell 和终端如何协作管理前台和后台进程。事情是这样的:

yes在交互式 shell 中运行。shellyes在单独的进程组1中生成。shell 通知终端(终端仿真器)新进程组现在位于前台。术语是前台进程组。shell 保留在其自己的进程组中,不再是前台进程组。shell 停止从终端读取数据,实际上是将其自身置于后台。

Ctrl+Z终端发送SIGSTP到前台进程组。Ctrl+C类似:信号是SIGINT,但它也转到前台进程组。

在您的例子中,SIGSTP被发送到yes进程。进程停止,其父进程(即 shell)收到SIGCHLD,因此它可以做出反应。shell 通过通知终端新的前台进程组是 shell 之一来做出反应。shell 恢复从终端读取。这样它就将自己置于前台。它打印提示并让您进行交互。

然后执行并发kill -s 18 …送到SIGCONT进程yes2 。

收到后,SIGCONT进程yes继续运行。它仍然在后台,即它的进程组没有变成前台进程组。它像在前台时一样打印到控制台3。整个情况就像你把停止的yes放到后台或像一开始bg一样在后台运行它一样。yes &

shell 仍然在前台。您尝试使用Ctrl+ZCtrl+时C,终端不断向 shell发送SIGSTP和。您的 shell 可能打印并重写了提示,但由于打印速度非常快(并且您的终端滚动速度非常快),您没有注意到。SIGINTSIGINT^Cyes

您可能没有注意到您可以在 shell 中键入命令。如果您键入fgEnter,shell 会通知终端 的进程组yes是新的前台进程组。shell 会将自身置于后台,就像您调用 之后一样yes然后您可以通过按+或+来发送SIGSTPSIGINT进入该流程。yesCtrlZCtrlC

尝试一下。


1简单 shell 或非交互式 shell(没有作业控制)可能会运行其进程组中的所有内容。yes但您所经历的情况表明它是在单独的进程组中生成的。

2在 Linux 中,数字 18 的具体含义取决于体系结构(请参阅man 7 signal)。根据您的描述,我可以判断它的含义SIGCONT(您可以通过检查 的输出来确认这一点kill -l)。一般来说POSIX 将一些数字与特定信号联系起来,但 18 不在这些数字中,也不SIGCONT在这些信号中。最便携的发送方式SIGCONT是使用kill -s CONT,而不是使用数字。这应该适用于任何符合 POSIX 标准的(或几乎符合 POSIX 标准的)操作系统。

3后台进程通常可以向其控制终端写入数据,但无法从中读取数据。调查SIGTTOUSIGTTIN详细情况,我这里就不多说了。

相关内容