[英]Why does my function return None everytime it is called even though it has a return statement
[英]Why does Popen.poll() return a return code of None even though the sub-process has completed?
我有一些在 Windows 上运行的 Python 代码,这些代码生成一个子进程并等待它完成。 子进程表现不佳,因此脚本进行非阻塞的 spawn 调用并在旁边监视进程。 如果达到某个超时阈值,它会终止进程,假设它已经脱离了轨道。
在某些不可重现的情况下,产生的子进程会消失,而观察程序不会注意到这个事实。 它会一直观察直到超过超时阈值,尝试杀死子进程并得到错误,然后退出。
什么可能导致子进程已经消失而观察者进程无法检测到这一事实? 为什么没有通过调用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
我看到的是,在进程消失的情况下,第 15 行对return_code = handle.poll()
的调用返回None
而不是返回代码。 我知道这个过程已经完全消失了——我可以看到它不再存在于任务管理器中。 而且我知道这个过程在达到超时值之前很久就消失了。
你能举一个你的 cmdline 变量的例子吗? 还有你在生成什么样的子进程?
我在测试脚本上运行它,使用以下命令调用批处理文件:
ping -n 151 127.0.0.1>nul
它工作正常。
可能是您的子流程没有正确终止。 另外,尝试将睡眠命令更改为 time.sleep(2) 之类的命令。
在过去,我发现这比长时间的睡眠更好(特别是如果您的子进程是另一个 python 进程)。
另外,我不确定你的脚本是否有这个,但在 else: 语句中,你有一个额外的括号。
else:
#print 'Process exited with return code: %i' % (return_code))
# There's an extra closing parenthesis
print 'Process exited with return code: %i' % (return_code)
break
以及如何在 join 语句中调用全局 temp_cmdline :
print 'Calling: %s' % (' '.join(temp_cmdline))
我不确定是否从列表变量 temp_cmdline 解析 cmdline,或者是否从空格分割的字符串创建 temp_cmdline。 无论哪种方式,如果您的 cmdline 变量是一个字符串,那么打印它是否更有意义?
print 'Calling: %s' % cmdline
子进程对象上的 poll 方法似乎不太好用。 当我产生一些线程来做一些工作时,我曾经遇到过同样的问题。 我建议你使用 multiprocessing 模块。
如果 stdout 被其他东西捕获,Popen.poll 不会按预期工作,您可以检查取出这部分代码“,stdout = subprocess.PIPE”
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.