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