我使用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。
答案 0 :(得分:6)
虽然我仍然不确定问题的确切原因,但我还有一些额外的意见和解决方法。
解决方法。强>
在finally子句中添加try-except
块。
finally:
try:
proc.terminate()
except WindowsError:
pass
这也似乎是在{{}}发布的相关(?)问题中得出的解决方案(您可能需要向下滚动一点)。
<强>观察。强>
proc.is_alive
在执行True
之前和之后返回proc.terminate()
(然后抛出WindowsError)。一两秒后,proc.is_alive()
返回False
,第二次拨打proc.terminate()
成功。time.sleep(1)
块中休眠finally
也可以防止抛出WindowsError。谢谢,@ tdelaney在OP中的评论。proc
的调用试图杀死时,proc.terminate()
正在释放内存(?或类似的东西),同时被操作系统杀死(已完成执行)它再次。