首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用KeyboardInterrupt终止子进程

使用KeyboardInterrupt终止子进程
EN

Stack Overflow用户
提问于 2016-09-15 05:32:32
回答 2查看 5.4K关注 0票数 5

我正在使用Python调用一个使用子进程模块的C++程序。由于程序运行需要一些时间,我希望能够使用Ctrl+C终止它。我在StackOverflow上看到了一些关于这方面的问题,但似乎没有一个解决方案对我有效。

我希望的是子进程在KeyboardInterrupt上终止。这是我的代码(类似于其他问题中的建议):

代码语言:javascript
复制
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。我也尝试过以下几种方法:

代码语言:javascript
复制
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()

这段代码可以很好地终止程序,所以问题并不是发送给terminate的实际信号。

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

我运行的是Python 2.7和64位Windows 7。提前感谢!

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

Python sub process Ctrl+C

Kill subprocess.call after KeyboardInterrupt

kill subprocess when python process is killed?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-09-15 13:24:16

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

代码语言:javascript
复制
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消耗。

票数 5
EN

Stack Overflow用户

发布于 2016-09-15 05:44:10

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

代码语言:javascript
复制
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 ignore。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39499959

复制
相关文章

相似问题

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