2009-11-05 2 views
1

Когда я пытаюсь убить процесс в окнах с помощью команд subprocess.Popen.terminate() или kill(), я получаю ошибку отказа в доступе. Мне действительно нужен кросс-платформенный способ завершить процесс, если файл больше не существует (да, я знаю, что это не самый элегантный способ делать то, что я делаю), я не хочу использовать вызовы платформы или import win32api, если это вообще возможно.Кросс-платформенный способ завершения процесса в python

Также - Как только я убью задачу, я должен просто удалить итерацию этой части библиотеки, нет? (Я помню, что-то читал о том, чтобы использовать кусочек, если я планирую работать над чем-то и изменить его во время работы на нем?)

#/usr/bin/env python 
#import sys 
import time 
import os 
import subprocess 
import platform 

ServerRange = range(7878, 7890) #Range of ports you want your server to use. 
cmd = 'VoiceChatterServer.exe' 

#********DO NOT EDIT BELOW THIS LINE******* 

def Start_IfConfExist(i): 
    if os.path.exists(str(i) + ".conf"): 
     Process[i] = subprocess.Popen(" " + cmd + " --config " + str(i) + ".conf", shell=True) 

Process = {} 

for i in ServerRange: 
    Start_IfConfExist(i) 

while True: 
    for i in ServerRange: 
     if os.path.exists(str(i) + ".conf"): 
      res = Process[i].poll() 
     if not os.path.exists(str(i) + ".conf"): #This is the problem area 
      res = Process[i].terminate()   #This is the problem area. 
     if res is not None: 
      Start_IfConfExist(i) 
      print "\nRestarting: " + str(i) + "\n" 
    time.sleep(1) 
+0

«Я не хочу использовать вызовы платформы или импортировать win32api, если это вообще возможно». В документации говорится, что это невозможно. Пожалуйста, проверьте SO для дублирования вопросов по этой точной теме. http://stackoverflow.com/questions/1064335/in-python-2-5-how-do-i-kill-a-subprocess –

+0

@ S.Lott: Я думаю, он имел в виду «явно вызывать API win32», в этот случай Popen.terminate будет называть его косвенно на Windows, а в Linux он будет использовать Posix. И ссылка, которую вы упомянули, не похожа на ту же проблему. – RedGlyph

+0

@ThantiK: Я думаю, что ошибка, которую вы получаете в Windows, связана с тем, что вы указываете 'shell = True', вам это действительно нужно? Если вы переключитесь на 'shell = False', не забывайте, что вам нужно указать аргументы в списке с именем процесса в качестве первого параметра, чтобы корректно работать в Linux. – RedGlyph

ответ

2

Вы можете легко сделать независимо от платформы вызов, делая что-то тривиальное, как:

try: 
    import win32 
    def kill(param): 
     # the code from S.Lotts link 
except ImportError: 
    def kill(param): 
     # the unix way 

Почему это не существует в python по умолчанию, я не знаю, но есть очень похожие проблемы в других областях, таких как уведомления об изменении файлов, где на самом деле не так сложно создать независимую от платформы lib (или в наименьший выигрыш + mac + linux). Я предполагаю, что это с открытым исходным кодом, поэтому вам нужно исправить это самостоятельно: P

+0

Да, это на самом деле тоже меня озадачило. Там действительно должен быть стандартный способ убить процесс, передав PID в win/linux/osx – ThantiK

+0

Риск с этим методом для Windows в любом случае заключается в том, что он убьет оболочку, но не дочерний процесс, если только внезапное отсутствие консоль для stdin/out/err приводит к сбою - именно это я наблюдаю в своей системе. Это означает, что дочерний процесс переключится на корневой проводник как родительский, а не на оболочку, и, возможно, все еще потребляет и блокирует ресурсы. Вывод: не используйте 'shell = True', если процесс должен быть убит. – RedGlyph

+0

Опять же, у меня нет выбора в этом вопросе. Исполняемый файл, который я запускаю, не может быть запущен без консоли. Если я устанавливаю оболочку в false, я получаю всевозможные ошибки python о том, что __init_ не происходит правильно, и т. Д. – ThantiK