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

Така че имам скрипт на Python, който изпълнява цикъл, в който извиква програма A чрез подпроцес. Popen изчаква нейния изход, след това запазва изхода и след това го извиква отново и т.н. (Това продължава да се случва за редица изпълнения, които съм задал като вход)

Работата е там, че имам таймер, така че когато програмата A отнеме повече от определен threshold_time, скриптът убива процеса с 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   

Имате ли някакви предложения какъв може да е проблемът?

РЕДАКТИРАНЕ: Приет отговор и коригиран код. Благодаря на @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

Дори ако убиете директно след анкета, която показва, че процесите се изпълняват, тя може да завърши преди да бъде изпълнен следващият ред. Бих предложил също така да добавите блок за опит и улавяне за това изключение и ако се случи, анкета отново, за да видите дали процесът действително е завършил.

person jedislight    schedule 02.06.2011
comment
Мисля че си прав. Пропуснах тази част. Благодаря, че забеляза! - person Galois; 04.06.2011
comment
Имам подобен проблем с пакета librosa / audioread, когато се опитвам да прочета mp3 файл. Но за съжаление трикът с пробване и улавяне не работи за мен - person Saw-mon and Natalie; 29.07.2017