调用Process.terminate时出现“WindowsError:Access被拒绝”

时间:2013-06-12 22:49:27

标签: python multiprocessing windowserror

我使用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。

1 个答案:

答案 0 :(得分:6)

虽然我仍然不确定问题的确切原因,但我还有一些额外的意见和解决方法。

解决方法。

在finally子句中添加try-except块。

finally:
    try:
        proc.terminate()
    except WindowsError:
        pass

这也似乎是在{{}}发布的相关(?)问题中得出的解决方案(您可能需要向下滚动一点)。

<强>观察。

  1. 此错误取决于传递给Process / Queue的对象的大小,但它与Process本身的执行无关。在OP中,进程在超时到期之前完成。
  2. proc.is_alive在执行True之前和之后返回proc.terminate()(然后抛出WindowsError)。一两秒后,proc.is_alive()返回False,第二次拨打proc.terminate()成功。
  3. 强制主线程在time.sleep(1)块中休眠finally也可以防止抛出WindowsError。谢谢,@ tdelaney在OP中的评论。
  4. 我最好的猜测是,当proc的调用试图杀死时,proc.terminate()正在释放内存(?或类似的东西),同时被操作系统杀死(已完成执行)它再次。