Duarte Arribas Asked: 2021-03-24 12:35:38 +0800 CST2021-03-24 12:35:38 +0800 CST 2021-03-24 12:35:38 +0800 CST 唤醒后无法杀死进程 772 我运行程序yes并按Ctrl+Z停止该过程。 之后,我通过执行将其唤醒kill -s 18 <pid>。 之后,我无法使用 + 再次停止它或使用+Ctrl杀死Z它。这是为什么?CtrlC linux process 1 个回答 Voted Best Answer Kamil Maciorowski 2021-03-24T15:32:10+08:002021-03-24T15:32:10+08:00 这完全是关于 shell 和终端如何协作来管理前台和后台进程。这就是发生的事情: 您yes在交互式外壳中运行。该外壳yes在一个单独的进程组1中产生。shell 通知终端(终端模拟器)新的进程组现在在前台。该术语是前台进程组。shell 保留在其自己的进程组中,该进程组不再是前台进程组。shell 停止从终端读取,实际上将自己置于后台。 在Ctrl+Z时,终端发送SIGSTP到前台进程组。Ctrl+C类似:信号是SIGINT,但它也进入前台进程组。 在你的情况下SIGSTP被发送到yes进程。进程停止并且它的父进程(即外壳)收到了SIGCHLD,所以它可以做出反应。外壳通过通知终端新的前台进程组做出反应是外壳之一。shell 继续从终端读取。这样,它就将自己置于前台。它打印了提示并让您进行交互。 然后你执行kill -s 18 …并发SIGCONT送到yes进程2。 收到后SIGCONT继续yes处理。它仍然在后台,即它的进程组没有成为前台进程组。它像在前台时一样打印到控制台3。整个情况就好像你把 stop 放到yes后台,bg或者像一开始一样在后台运行它yes &。 壳仍然在前景中。Ctrl您对+Z和Ctrl+的尝试C不断使终端发送并发SIGSTP送到SIGINT外壳。在SIGINT您的外壳上可能打印^C并重写了提示,但由于yes打印速度非常快(并且您的终端滚动速度非常快),您没有注意到。 而且您可能没有注意到您可以在 shell 中键入命令。如果您键入fgEnter,shell 将通知终端进程组yes是新的前台进程组。shell 会自己后台运行,就像在您调用yes. 然后,您可以通过点击+或+来发送SIGSTP或发送SIGINT到该yes进程。CtrlZCtrlC 试试看。 1简单 shell 或非交互式 shell(没有作业控制)可以运行其进程组中的所有内容。您所经历的表明yes是在一个单独的进程组中产生的。 2在 Linux 中,数字 18 的确切含义取决于体系结构(请参阅 参考资料man 7 signal)。根据您的描述,我可以说是SIGCONT(您可以通过检查 的输出来确认这一点kill -l)。一般来说, POSIX 将很少的数字连接到特定的信号,但 18 不在这些数字中,SIGCONT也不在这些信号中。最便携的发送方式SIGCONT是使用kill -s CONT,而不是使用数字。这应该适用于任何符合 POSIX(或几乎符合 POSIX)的操作系统。 3后台进程通常可以写入其控制终端;它无法从中读取。细究一下SIGTTOU,SIGTTIN这里就不细说了。
这完全是关于 shell 和终端如何协作来管理前台和后台进程。这就是发生的事情:
您
yes
在交互式外壳中运行。该外壳yes
在一个单独的进程组1中产生。shell 通知终端(终端模拟器)新的进程组现在在前台。该术语是前台进程组。shell 保留在其自己的进程组中,该进程组不再是前台进程组。shell 停止从终端读取,实际上将自己置于后台。在Ctrl+Z时,终端发送
SIGSTP
到前台进程组。Ctrl+C类似:信号是SIGINT
,但它也进入前台进程组。在你的情况下
SIGSTP
被发送到yes
进程。进程停止并且它的父进程(即外壳)收到了SIGCHLD
,所以它可以做出反应。外壳通过通知终端新的前台进程组做出反应是外壳之一。shell 继续从终端读取。这样,它就将自己置于前台。它打印了提示并让您进行交互。然后你执行
kill -s 18 …
并发SIGCONT
送到yes
进程2。收到后
SIGCONT
继续yes
处理。它仍然在后台,即它的进程组没有成为前台进程组。它像在前台时一样打印到控制台3。整个情况就好像你把 stop 放到yes
后台,bg
或者像一开始一样在后台运行它yes &
。壳仍然在前景中。Ctrl您对+Z和Ctrl+的尝试C不断使终端发送并发
SIGSTP
送到SIGINT
外壳。在SIGINT
您的外壳上可能打印^C
并重写了提示,但由于yes
打印速度非常快(并且您的终端滚动速度非常快),您没有注意到。而且您可能没有注意到您可以在 shell 中键入命令。如果您键入
fg
Enter,shell 将通知终端进程组yes
是新的前台进程组。shell 会自己后台运行,就像在您调用yes
. 然后,您可以通过点击+或+来发送SIGSTP
或发送SIGINT
到该yes
进程。CtrlZCtrlC试试看。
1简单 shell 或非交互式 shell(没有作业控制)可以运行其进程组中的所有内容。您所经历的表明
yes
是在一个单独的进程组中产生的。2在 Linux 中,数字 18 的确切含义取决于体系结构(请参阅 参考资料
man 7 signal
)。根据您的描述,我可以说是SIGCONT
(您可以通过检查 的输出来确认这一点kill -l
)。一般来说, POSIX 将很少的数字连接到特定的信号,但 18 不在这些数字中,SIGCONT
也不在这些信号中。最便携的发送方式SIGCONT
是使用kill -s CONT
,而不是使用数字。这应该适用于任何符合 POSIX(或几乎符合 POSIX)的操作系统。3后台进程通常可以写入其控制终端;它无法从中读取。细究一下
SIGTTOU
,SIGTTIN
这里就不细说了。