WindowsError: [错误 5] 访问被拒绝,无法终止子进程(python)
我有一个Python脚本,它在一个循环中运行,里面调用了一个程序A,通过subprocess.Popen来等待它的输出,然后保存这个输出,再继续调用它,反复进行下去。(这个过程会根据我设定的输入次数不断重复)
这个脚本里有一个定时器,意思是如果程序A运行时间超过了我设定的某个阈值,脚本就会用process.kill()来结束这个进程,然后继续进行下一次循环。
问题是,虽然在300次运行的时候一切看起来都很正常,但有时候我会遇到这样的错误:
File "C:\Python27\lib\subprocess.py", line 1002, in terminate
_subprocess.TerminateProcess(self._handle, 1)
WindowsError: [Error 5] Access is denied
然后脚本就崩溃了。
相关的脚本部分:
timeout = TIME_CONST
for run in runs:
killed = False
start = time.clock()
p = subprocess.Popen("SOME.CMD", cwd=r"some_dir")
# Monitor process. If it hits threshold, kill it and go to the next run
while p.poll() is None:
time.sleep(20)
secs_passed = time.clock() - start
### the following was my initial buggy line ###
#if secs_passed >= timeout:
### corrected line after jedislight's answer ###
#if the time is over the threshold and process is still running, kill it
if secs_passed >= timeout and p.poll is None:
p.kill()
killed = True
break
if killed: continue
你们有什么建议,觉得问题可能出在哪里吗?
补充: 我已经接受了答案并修复了代码。感谢@jedislight的反馈!
1 个回答
8
你在调用 p.poll() 和 p.kill() 之间隔了20秒。这段时间内,进程可能已经结束了。我建议你调整一下时间,让这两个操作在同一时间段内进行,这样就能避免去杀死一个已经结束的进程。下面是一个在 iPython 中运行的例子,展示了在杀死一个已经完成的进程时出现的类似错误:
In [2]: import subprocess
In [3]: p = subprocess.Popen("dir")
In [4]: p.poll()
Out[4]: 0
In [5]: p.kill()
---------------------------------------------------------------------------
WindowsError Traceback (most recent call last)
C:\Users\---\<ipython console> in <module>()
C:\Python26\lib\subprocess.pyc in terminate(self)
947 """Terminates the process
948 """
--> 949 _subprocess.TerminateProcess(self._handle, 1)
950
951 kill = terminate
WindowsError: [Error 5] Access is denied
即使你在检查进程状态后立刻去杀死它,如果在执行下一行代码之前进程已经结束了,也会出现问题。我还建议你加一个 try-catch 结构来处理这个异常,如果发生了,就再检查一次,看看进程是否真的完成了。