"Ошибка WindowsE: доступ запрещен" при вызове Process.terminate
Я применяю таймаут для блока кода, используя 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
Разрешено ли мне прекратить процесс определенного размера?
Я использую Python 2.7 на Windows 7 (64bit).
1 ответ
Хотя я все еще не уверен относительно точной причины проблемы, у меня есть некоторые дополнительные наблюдения, а также обходной путь.
Обходной путь.
Добавление try-except
блок в окончательном предложении.
finally:
try:
proc.terminate()
except WindowsError:
pass
Похоже, что это также решение проблемы, связанной с (?), Размещенной здесь на GitHub (возможно, вам придется немного прокрутить вниз).
Наблюдения.
- Эта ошибка зависит от размера объекта, передаваемого в процесс / очередь, но не связана с выполнением самого процесса. В OP процесс завершается до истечения времени ожидания.
proc.is_alive
возвращаетсяTrue
до и после исполненияproc.terminate()
(который затем выбрасывает WindowsError). Через секунду или две,proc.is_alive()
возвращаетсяFalse
и второй звонокproc.terminate()
преуспевает.- Заставляя основной поток спать
time.sleep(1)
вfinally
Блок также предотвращает выброс WindowsError. Спасибо, комментарий @tdelaney в ОП. - Я думаю, что
proc
находится в процессе освобождения памяти (?, или что-то сопоставимое) во время уничтожения ОС (после завершения выполнения) при обращении кproc.terminate()
пытается убить его снова.