WindowsError: [Ошибка 5] Доступ запрещен при попытке уничтожить подпроцесс (python) - PullRequest
9 голосов
/ 07 апреля 2011

Итак, у меня есть скрипт на python, который запускает цикл, в котором он вызывает программу A через подпроцесс. Popen ожидает его вывода, затем сохраняет вывод, а затем вызывает его снова и так далее.(Это продолжает происходить для ряда запусков, которые я установил в качестве входных данных)

Дело в том, что у меня есть таймер, так что, когда программа A занимает больше определенного порогового времени, сценарий убивает процесс с процессом.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 Ответ

6 голосов
/ 02 июня 2011

Вы разделяете свои p.poll () и p.kill () на 20 секунд. К тому времени процесс мог закончиться. Я бы посоветовал переместить вызов time.sleep (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 для этого исключения и, если это произойдет, снова опросить, чтобы увидеть, действительно ли процесс завершен.

...