首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >目标KeyboardInterrupt到子进程

目标KeyboardInterrupt到子进程
EN

Stack Overflow用户
提问于 2016-07-20 18:16:36
回答 3查看 1.4K关注 0票数 0

我希望在Python中启动一个运行时间相当长的子进程,并希望能够使用^C终止它。但是,按^C会导致父进程接收KeyboardInterrupt并终止(有时会将sleep作为一个已失效的进程)。

代码语言:javascript
复制
import subprocess
subprocess.call("sleep 100".split())

如何使按下^C只终止sleep进程(就像在shell命令行中那样),并允许父进程继续?我相信我尝试过将preexec_fnstart_new_sessionshell标志组合到call中,但没有成功。

编辑:我知道可以将subprocess调用封装在try-catch块中,而忽略键盘中断;但我不想这样做。我的问题是:键盘中断应该杀死sleep,并且应该是它的结束。为什么会像以前一样被传播到父母身上。还是sleep进程从来都不是接收中断的那个进程?如果没有,我将如何使它成为前台过程?

同样,我试图模仿命令行的父-子关系。如果我要在命令行上执行等效的操作,我可以不需要额外的处理就可以逃脱。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-07-22 08:10:57

正如雅各布所建议的那样,有一种方法(多亏了同事)就是处理信号,并将信号传递给孩子。所以像这样的包装应该是:

代码语言:javascript
复制
import signal
import subprocess

def run_cmd(cmd, **kwargs):
    try:
        p = None

        # Register handler to pass keyboard interrupt to the subprocess
        def handler(sig, frame):
            if p:
                p.send_signal(signal.SIGINT)
            else:
                raise KeyboardInterrupt
        signal.signal(signal.SIGINT, handler)

        p = subprocess.Popen(cmd, **kwargs)
        if p.wait():
            raise Exception(cmd[0] + " failed")
    finally:
        # Reset handler
        signal.signal(signal.SIGINT, signal.SIG_DFL)
票数 0
EN

Stack Overflow用户

发布于 2016-07-20 18:22:26

使用signal捕获SIGINT,并使信号处理程序终止子进程。

有关更多信息(如果是Python2.x的话),请看这个:

https://docs.python.org/2/library/signal.html

票数 1
EN

Stack Overflow用户

发布于 2016-07-20 18:24:33

不确定这是否是一个解决办法,但它可以正常工作(至少在不同处理CTRL+C的Windows上是这样的)

代码语言:javascript
复制
import subprocess
try:
    subprocess.call(r"C:\msys64\usr\bin\sleep 100".split())
except KeyboardInterrupt:
    print("** BREAK **")
print("continuing the python program")

处决:

代码语言:javascript
复制
K:\jff\data\python>dummy_wait.py
** BREAK **
continuing the python program
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38487972

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档