我使用 multiprocessing
模块对代码块强制执行超时。似乎对于某些大小的输入,会引发以下错误:
WindowsError: [Error 5] Access is denied
我可以使用以下代码重现此错误。请注意,代码以“467,912,040”结束,但不以“517,912,040”结束。
import multiprocessing, Queue
def wrapper(queue, lst):
lst.append(1)
queue.put(lst)
queue.close()
def timeout(timeout, lst):
q = multiprocessing.Queue(1)
proc = multiprocessing.Process(target=wrapper, args=(q, lst))
proc.start()
try:
result = q.get(True, timeout)
except Queue.Empty:
return None
finally:
proc.terminate()
return result
if __name__ == "__main__":
# lst = [0]*417912040 # this works fine
# lst = [0]*467912040 # this works fine
lst = [0] * 517912040 # this does not
print "List length:",len(lst)
timeout(60*30, lst)
输出(包括错误):
List length: 517912040
Traceback (most recent call last):
File ".\multiprocessing_error.py", line 29, in <module>
print "List length:",len(lst)
File ".\multiprocessing_error.py", line 21, in timeout
proc.terminate()
File "C:\Python27\lib\multiprocessing\process.py", line 137, in terminate
self._popen.terminate()
File "C:\Python27\lib\multiprocessing\forking.py", line 306, in terminate
_subprocess.TerminateProcess(int(self._handle), TERMINATE)
WindowsError: [Error 5] Access is denied
是否不允许我终止特定大小的进程?
我在 Windows 7(64 位)上使用 Python 2.7。
最佳答案
虽然我仍然不确定问题的确切原因,但我有一些额外的观察结果和解决方法。
解决方法。
在 finally 子句中添加一个 try-except
block 。
finally:
try:
proc.terminate()
except WindowsError:
pass
这似乎也是在发布的相关(?)问题中得出的解决方案 here on GitHub (您可能需要向下滚动一点)。
观察。
- 此错误取决于传递给进程/队列的对象的大小,但与进程本身的执行无关。在 OP 中,进程在超时到期前完成。
proc.is_alive
在执行proc.terminate()
之前和之后返回True
(然后抛出 WindowsError)。一两秒后,proc.is_alive()
返回False
,第二次调用proc.terminate()
成功。- 在
finally
block 中强制主线程休眠time.sleep(1)
也可以防止抛出 WindowsError。谢谢,@tdelaney 在 OP 中的评论。 - 我最好的猜测是
proc
正在释放内存(?,或类似的东西),同时在调用proc 时被操作系统杀死(已完成执行)。 terminate()
尝试再次杀死它。
关于python - "WindowsError: Access is denied"调用 Process.terminate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17076679/