2015-02-13 5 views
-1

Я запускаю программу test.py. Поскольку он часто рушится, я импортирую subprocess, чтобы перезагрузить его, когда он остановится. Иногда я обнаружил, что подпроцесс не может его успешно перезапустить. Следовательно, я заставляю программу перезапускать каждые 60 минут. Но я обнаружил, что иногда две тестовые обработки работают симулятивно. Что случилось с моим кодом и как его исправить? Я использую ОС Windows 7. Plz проверить следующие коды и спасибо заранее:Почему подпроцесс не может успешно убить старый запущенный процесс?

import subprocess 
import time 
from datetime import datetime 

p = subprocess.Popen(['python.exe', r'D:\test.py'], shell=True) 
minutes = 1 
total_time = 0 
while True: 
    now = datetime.now() 

    #periodly restart 
    total_time += 1 
    if total_time % 100 == 0: 
     try: 
      p.kill() 
     except Exception as e: 
      terminated = True 
     finally: 
      p = subprocess.Popen(['python.exe', r'D:\test.py'], shell=True) 

    #check and restart if it stops 
    try: 
     terminated = p.poll() 
    except Exception as e: 
     terminated = True 
    if terminated: 
     p = subprocess.Popen(['python.exe', r'D:\test.py'], shell=True) 
    time.sleep(minutes * 60) 
+0

drop 'shell = True' - он создает ненужный здесь процесс' cmd.exe' ('p.kill()' убивает этот процесс). – jfs

+0

related: [subprocess не может успешно перезапустить целевой файл python] (http://stackoverflow.com/q/28302081/4279) – jfs

ответ

0

Хотя я не согласен с вашим дизайном, конкретная проблема здесь:

except Exception as e: 
     terminated = True 
finally: 
     p = subprocess.Popen(['python.exe', r'D:\test.py'], shell=True) 

В случае, что Exception был throw, вы устанавливаете terminated в true, но затем сразу же перезапускаете подпроцесс. Потом, позже, вы проверяете:

if terminated: 
    p = subprocess.Popen(['python.exe', r'D:\test.py'], shell=True) 

На данный момент terminated является true, поэтому он начинает новый подпроцесс. Однако он уже сделал это в блоке finally.

Действительно, то, что вы должны сделать, это просто не беспокоить его перезапуск при попытке убить:

try: 
     p.kill() 
    except Exception: 
     # We don't care, just means it was already dead 
     pass 
    finally: 
     # Either the process is dead, or we just killed it. Either way, need to restart 
     terminated = True 

Тогда ваша статья if terminated будет правильно перезапустить процесс, и вы не будете иметь дубликат.

+0

Не могу согласиться с вами больше. Спасибо. –

+0

Вы упомянули, что «В этот момент завершение выполняется верно, поэтому он запускает новый подпроцесс». Но так как я перезапускаю его в разделе «finally», должен «закончить == None» в следующем разделе «try»? Вы имеете в виду, что этот период слишком короткий, чтобы программа запускалась снова, так что в этот момент «terminated == True»? –

+0

Вы не перезапускаете скрипт, вызывающий эти вызовы, вы перезапускаете его дочерний процесс 'p'. Во всяком случае, второй блок 'try' не влияет на оценку оператора if if terminated, который всегда проверяется на каждую итерацию цикла while. – aruisdante

Смежные вопросы