繁体   English   中英

使用KeyboardInterrupt终止子进程

[英]Terminating a subprocess with KeyboardInterrupt

我正在使用Python使用subprocess模块​​调用C ++程序。 由于该程序需要花费一些时间才能运行,因此我希望能够使用Ctrl + C终止该程序。 我在StackOverflow上看到了一些与此有关的问题,但是似乎没有一种解决方案适合我。

我想要的是子进程在KeyboardInterrupt上终止。 这是我拥有的代码(类似于其他问题的建议):

import subprocess

binary_path = '/path/to/binary'
args = 'arguments' # arbitrary

call_str = '{} {}'.format(binary_path, args)

proc = subprocess.Popen(call_str)

try:
    proc.wait()
except KeyboardInterrupt:
    proc.terminate()

但是,如果运行此命令,则代码将挂起,等待进程结束,并且永远不会注册KeyboardInterrupt。 我也尝试了以下方法:

import subprocess
import time

binary_path = '/path/to/binary'
args = 'arguments' # arbitrary

call_str = '{} {}'.format(binary_path, args)

proc = subprocess.Popen(call_str)
time.sleep(5)
proc.terminate()

该代码段可以很好地终止程序,因此问题出在,不是发出终止信号的实际信号。

如何更改代码,以便可以在KeyboardInterrupt上终止子进程?

我正在运行Python 2.7和Windows 7 64位。 提前致谢!

我尝试过的一些相关问题:

Python子进程Ctrl + C

KeyboardInterrupt后杀死subprocess.call

杀死python进程时杀死子进程?

我想出了一种方法,类似于让-弗朗索瓦(Jean-Francois)对循环的回答,但没有多个线程。 关键是使用Popen.poll()确定子进程是否已完成(如果仍在运行,则将返回None)。

import subprocess
import time

binary_path = '/path/to/binary'
args = 'arguments' # arbitrary

call_str = '{} {}'.format(binary_path, args)

proc = subprocess.Popen(call_str)

try:
    while proc.poll() is None:
        time.sleep(0.1)

except KeyboardInterrupt:
    proc.terminate()
    raise

我在KeyboardInterrupt之后添加了一个额外的加薪,因此除了子进程之外,Python程序也被中断了。

编辑:根据eryksun的注释将pass更改为time.sleep(0.1),以减少CPU消耗。

我在Windows上的丑陋但成功的尝试:

import subprocess
import threading

import time

binary_path = 'notepad'
args = 'foo.txt' # arbitrary

proc = None
done = False

def s():
    call_str = '{} {}'.format(binary_path, args)
    global done
    global proc
    proc = subprocess.Popen(call_str,stdout=subprocess.PIPE)
    proc.wait()
    done = True


t = threading.Thread(target=s)
t.start()


try:
    while not done:
        time.sleep(0.1)

except KeyboardInterrupt:
    print("terminated")
    proc.terminate()

在运行子进程的地方创建一个线程。 导出proc变量。

然后在非活动循环中永远等待。 当按CTRL + C时,将触发异常。 进程间通信(例如: proc.wait() )与CTRL + C处理发生冲突。 在线程中运行时,没有这样的问题。

注意:我已经尝试使用threading.lock()来避免这个时间循环,但是偶然发现了相同的CTRL + C忽略。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM