1 回答

TA贡献1752条经验 获得超4个赞
我们将假设一个类Unix系统,使用一个理解并参与工作控制的shell(他们现在都这样做了)。运行命令时,shell 会创建一个称为进程组或“pgroup”的东西来保存组成该命令的每个进程。如果命令是一个管道(就像这个一样),则管道中的每个进程都会获得相同的 pgroup-ID(请参阅 setpgid
)。
如果命令在 forgeground 中运行(不带 ),则控制终端会分配此特定 pgid。按下其中一个信号生成键,例如或,使用内部 killpg
或等效项将相应的信号(在这些情况下)发送到 p 组。这会将信号发送到 p 组的每个成员。&
CTRL-CCTRL-\SIGINT
SIGQUIT
(后台处理进程只是*咳嗽*,收回控制tty上的pgid,然后重新启动管道中的进程。但是,实现这一目标并不是那么简单,正如此处的“重新启动”所示。
这里问题的可能根源是,交互式程序将控制终端置于cbreak或原始模式,并禁用来自键盘键的部分或全部信号,例如,不再导致内核的tty模块发送信号。相反,如果您看到一个密钥应导致挂起 () 或终止,则程序必须执行自己的挂起或终止。程序员有时认为这包括简单地挂起或终止 - 但是由于整个管道从未获得有问题的信号,因此情况并非如此,除非整个shell管道仅由交互式程序组成。CTRL-CCTRL-Z
解决方法是让程序在对控制终端进行任何必要的清理(临时或永久)后将信号发送到自己的p组。
- 1 回答
- 0 关注
- 118 浏览
添加回答
举报