Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用键盘中断终止子进程 我使用Python调用子进程模块的C++程序。由于程序运行需要一些时间,我希望能够使用Ctrl+C终止它。我在StackOverflow上看到了一些关于这方面的问题,但没有一个解决方案适合我_Python_Windows_Subprocess_Interrupt_Terminate - Fatal编程技术网

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

用键盘中断终止子进程 我使用Python调用子进程模块的C++程序。由于程序运行需要一些时间,我希望能够使用Ctrl+C终止它。我在StackOverflow上看到了一些关于这方面的问题,但没有一个解决方案适合我,python,windows,subprocess,interrupt,terminate,Python,Windows,Subprocess,Interrupt,Terminate,我希望子进程在键盘中断时终止。这是我的代码(类似于其他问题中的建议): 但是,如果我运行这个,代码将挂起,等待进程结束,并且从不注册键盘中断。我也尝试过以下方法: import subprocess import time binary_path = '/path/to/binary' args = 'arguments' # arbitrary call_str = '{} {}'.format(binary_path, args) proc = subprocess.Popen(cal

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

但是,如果我运行这个,代码将挂起,等待进程结束,并且从不注册键盘中断。我也尝试过以下方法:

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()
这个代码段在终止程序时工作得很好,所以问题不是发送给终止程序的实际信号

如何更改代码,以便在键盘中断时终止子进程

我正在运行Python2.7和Windows7 64位。提前谢谢

我试过的一些相关问题:


我在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 ignore。

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

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


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

为什么不在主程序中捕获ctrl-c信号并使用它调用
proc.terminate()
?在Python 3中,可以使用
\u winapi.WaitForMultipleObjects([proc.\u handle],False,-1)
。对于主线程,如果wait all标志为false,则此等待将自动包括Python的
SIGINT
事件。在2.x中,您必须使用ctypes或PyWin32从头开始实现此功能。@eryksun感谢您的建议。有一个名为win32event的模块具有类似的函数,可以为Python 2导入,但我尝试了
win32event.WaitForMultipleObjects([proc.\u handle],False,-1)
,但没有任何区别。@limi44,3.x使用由Ctrl+C的信号处理程序设置的Windows事件对象。调用
\u winapi.WaitForMultipleObjects
时,此事件会自动添加到列表中。在2.x中实现此功能需要PyWin32或ctypes定义一个控制台
CTRL\u事件
处理程序(例如,将ctypes回调函数传递给
SetConsoleCtrlHandler
),该处理程序设置一个事件(通过
CreateEvent
创建)。然后,您需要包装
WaitForMultipleObjects
,将Ctrl+C事件句柄附加到列表中,并在等待之前重置事件(
ResetEvent
),但仅在从主线程调用时才重置。
time.sleep(.1)
是可中断的。使用它而不是
pass
可以减少CPU消耗。
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()
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