Python 如果执行Ctrl+;C当一个子进程正在执行时?
给定以下代码:Python 如果执行Ctrl+;C当一个子进程正在执行时?,python,Python,给定以下代码: try: subprocess.Popen(ExternalProcess, stdout=subprocess.PIPE,stderr=subprocess.PIPE, shell=True).communicate() except KeyboardInterrupt: exit(0) 如果在执行ExternalProcess(这不是python脚本)的过程中,按下Ctrl+C命令,到底发生了什么 在这个范围内,如果我按下Ctrl+C,即使在执行ExternalPr
try:
subprocess.Popen(ExternalProcess, stdout=subprocess.PIPE,stderr=subprocess.PIPE, shell=True).communicate()
except KeyboardInterrupt:
exit(0)
如果在执行ExternalProcess
(这不是python脚本)的过程中,按下Ctrl+C命令,到底发生了什么
在这个范围内,如果我按下Ctrl+C,即使在执行ExternalProcess
的过程中发生,我是否可以100%确保它始终进入“除外”状态
还是取决于外部过程如何处理 据我所知,一旦您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
我假设您在我的回答中使用了Unix变体。我对Windows世界没有更深入的了解 如果所有配置都正常,则
C-C
将由终端(xterm、gnome终端,…)解释。该终端将向连接到与该终端相关的tty设备的processgroup的所有进程发送一个SIGINT(请参阅kill-l
,以了解系统的编号,通常为2)。这就是shell或shell启动的程序(以及它的所有子进程,因为进程组被继承)
但是,孩子可以自愿离开其流程组并创建一个新的流程组。守护进程通常这样做是为了避免被父程序中按下的Ctrl-C意外杀死。这不准确。当父级退出时,
SIGINT
被发送给子级,而不是当您按下Ctrl+C
时。没有传播。例如,如果在父级中除了KeyboardInterrupt之外,在之后放置一个循环,则SIGINT
不会到达子级。但我不确定进程组。@freakish我刚刚添加了,而True:pass
到a.py
的末尾,child仍在接收SIGINT
。此外,如果在父级退出后传递了SIGINT
,为什么要先打印b.py的ctrl-c
?我想这可能是Python的.communicate
的一个功能?例如,如果您执行pr=subprocess.Popen(…)
(没有。通信
),然后循环使用try:time.sleep(1)除了:pass
。@freakish对我来说传播很好。如果选中Popen.communicate()
source,则其中没有关于信号传播的内容。另请参见。@freakish:终端向同一进程组的所有成员发送信号。请参阅以下是C API的process group和Ctrl+C的一个简单示例,这可能会提供一些见解: