28

给定以下代码:

try:
  subprocess.Popen(ExternalProcess, stdout=subprocess.PIPE,stderr=subprocess.PIPE, shell=True).communicate()
except KeyboardInterrupt:
  exit(0)

如果在执行ExternalProcess(不是 python 脚本)期间按下Ctrl+C命令,到底发生了什么?

我可以确定 100% 在这个范围内,如果我按Ctrl+ C,即使它在执行期间发生,它也会始终进入“除外” ExternalProcess

还是取决于外部进程如何处理它?

4

2 回答 2

20

据我了解,一旦你 fork/exec 一个进程,它就会继承父进程组。这意味着,那个SIGINT(这是 的结果Ctrl+C和原因KeyboardInterrupt)将被发送给孩子和父母。

这是一个例子:

文件a.py

import subprocess

try:
    subprocess.Popen("python b.py".split()).communicate()
except KeyboardInterrupt:
    print "a.py got ctrl-c"

文件b.py

try:
    while True: pass
except KeyboardInterrupt:
    print "b.py got ctrl-c"

现在你运行它并停止:

> python a.py
^Cb.py got ctrl-c
a.py got ctrl-c
于 2013-11-06T08:49:37.553 回答
2

我假设您在我的回答中使用的是 Unix 变体。我对 Windows 世界没有更深入的了解。

如果一切都配置正常,那么C-c终端将解释(xterm,gnome-terminal,...)。kill -l此终端将向附加到与此终端关联的 tty 设备的进程组的所有进程发送 SIGINT(请参阅了解您的系统编号,通常为 2)。那是 shell 或 shell 启动的程序(以及它的所有子进程,因为进程组被继承)。

但是,子进程可以自愿离开其进程组并创建一个新进程组。守护进程通常这样做是为了避免被Ctrl-C父程序中的按下意外杀死。

于 2013-11-06T08:52:35.580 回答