WindowsError: [Ошибка 5] Отказано в доступе при попытке убить подпроцесс (python)

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

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

У вас есть предложения, в чем может быть проблема?

EDIT: Принят ответ и исправлен код. Спасибо @jedislight за ваш отзыв!


person Galois    schedule 06.04.2011    source источник
comment
Можете ли вы опубликовать самый маленький скрипт Python, который может воспроизвести такое поведение?   -  person Sridhar Ratnakumar    schedule 07.04.2011
comment
@Sridhar Я добавил код, который вы просили.   -  person Galois    schedule 08.04.2011
comment
Я попробовал это с SOME.CMD, будучи просто cmd, и это сработало. Какой процесс вы пытаетесь убить?   -  person Fenikso    schedule 13.04.2011
comment
Это может произойти, если процесс делает что-то с повышенными привилегиями. Предполагая, что ваша учетная запись локального администратора называется Admin, subprocess.Popen("runas /user:Admin cmd.exe"), вероятно, вызовет такое же исключение, если вы предоставите пароль до того, как скрипт попытается его убить.   -  person robots.jpg    schedule 02.06.2011


Ответы (1)


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

person jedislight    schedule 02.06.2011
comment
Я думаю, вы правы. Я пропустил эту часть. Спасибо, что заметили! - person Galois; 04.06.2011
comment
У меня аналогичная проблема с пакетом librosa/audioread при попытке прочитать mp3-файл. Но, к сожалению, трюк с попыткой поймать не работает для меня. - person Saw-mon and Natalie; 29.07.2017