我有一些在 Windows 上运行的 Python 代码,它产生一个子进程并等待它完成。子进程表现不佳,因此脚本会进行非阻塞生成调用并在旁边监视进程。如果达到某个超时阈值,它会终止进程,假设它已经脱离了轨道。
在某些不可重现的情况下,生成的子进程将消失,并且观察者例程不会注意到这一事实。它会一直观察直到超过超时阈值,尝试杀死子进程并得到错误,然后退出。
什么可能导致子进程已经消失而无法被观察者进程检测到?为什么调用 to 时没有捕获和返回返回码Popen.poll()
?
我用来生成和观察过程的代码如下:
import subprocess
import time
def nonblocking_subprocess_call(cmdline):
print 'Calling: %s' % (' '.join(cmdline))
p = subprocess.Popen(cmdline, shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
return p
def monitor_subprocess(handle, timeout=1200):
start_time = time.time()
return_code = 0
while True:
time.sleep(60)
return_code = handle.poll()
if return_code == None:
# The process is still running.
if time.time() - start_time > timeout:
print 'Timeout (%d seconds) exceeded -- killing process %i' % (timeout, handle.pid)
return_code = handle.terminate()
# give the kill command a few seconds to work
time.sleep(5)
if not return_code:
print 'Error: Failed to kill subprocess %i -- return code was: %s' % (handle.pid, str(return_code))
# Raise an error to indicate that the process was hung up
# and we had to kill it.
raise RuntimeError
else:
print 'Process exited with return code: %i' % (return_code)
break
return return_code
我所看到的是,在进程消失的情况下,return_code = handle.poll()
对第 15 行的调用正在返回None
而不是返回代码。我知道这个过程已经完全消失了——我可以看到它不再存在于任务管理器中。而且我知道该过程在达到超时值之前很久就消失了。