2013-12-02 2 views
1

Я только что открыл модуль 'envoy', обертка для подпроцесса python, созданного создателем запросов.Как избежать процесса зомби с помощью envoy.connect?

У меня проблема с функцией «connect»: каждый раз, когда я ее использую, это приводит к процессу зомби, и я не могу получить status_code или результат.

c=envoy.connect("ls -al") 
c.status_code == None 
True 

Если я делаю 'пс -ef | Grep thepid', я получаю 'несуществующей' ПИД-регулятора.

Я могу убить зомби, делая os.wait() или c._process.wait(), но я не могу получить результат (стандартный вывод) из моей команды ...

Любая идея ?

+0

После более глубокого рассмотрения моей проблемы, я думаю, что это связано с платформой/pythonVersion: я использую python 2.6 на Solaris10 (x86) и событие, которое тестовые данные, данные с посланником, не работают. с = envoy.connect ("сна 1") time.sleep (2) self.assertEqual (c.status_code, 0) ==> Сохраняет имеющий зомби процедурный и 'None' status_code. К сожалению, у меня нет возможности обновить python, так как это зависит от другой команды. Я выполняю некоторые тесты на машине linux ... – SuperPython

ответ

1

В вашем случае вы должны использовать run() метод

Как представитель документации рекомендует:

r = envoy.run(cmd) 
print r.status_code, r.std_out 

Но в случае, если вы хотите, чтобы команда запуска асинхронно вы можете использовать connect()с последующим block()

Вызывается block(), код возврата становится доступным. Но block() блокирует вашу программу, поэтому логика должна быть.

c1=envoy.connect(cmd1) 
c2=envoy.connect(cmd2) 
c3=envoy.connect(cmd3) 
... more staff ... 
c1.block() 
print c1.status_code 
+0

run() работает нормально, но я хотел использовать connect() для неблокирующих процессов. Мой скрипт должен запустить десятую часть команд. «Ls -al» был здесь, например, цели. Фактическая команда занимает почти одну минуту, чтобы отправить результат ... – SuperPython

+0

Да, я понимаю. Исправлен ответ, посмотрите, помогает ли он. – LiMar

+1

+1 для '.block()'. 'del c1' также должен привести к пожиранию процесса зомби. – jfs

1

, но я не могу получить результат (стандартный вывод) из моей команды ...

ConnectedCommand (тип, возвращаемый envoy.connect()), кажется, не будет готов. В частности, команда может затормозить, если она получает/генерирует достаточно (в зависимости от платформы) вход/выход.

В дополнение к телефону c.block(), который также работает для живых процессов; вы можете удалить все ссылки на команду и использовать del c, чтобы получить зомби. Если подпроцессы не мертвы; они не будут извлекаться до тех пор, пока метод очистки не будет запущен при запуске следующего подпроцесса (это зависит от реализации).

Если для вашей задачи недостаточно возможностей envoy.run(); вы можете напрямую использовать модуль subprocess. Например, чтобы передать входные данные нескольким процессам и собрать соответствующие результаты; вы могли бы использовать ThreadPool и .communicate() метод:

#!/usr/bin/env python 
from multiprocessing.pool import ThreadPool 
from subprocess import Popen, PIPE 

def process(child_input): 
    child, input = child_input # unpack arguments 
    return child.communicate(input)[0], child.returncode # get the result 


# define input to be pass to subprocesses 
params = b"a b c".split() 

# start subprocesses (the command is just an example, use yours instead) 
children = [Popen("(echo -n {0}; sleep {0}; cat)".format(len(params) - i), 
        shell=True, stdin=PIPE, stdout=PIPE) 
      for i in range(len(params))] 

# use threads to wait for results in parallel 
pool = ThreadPool(len(params)) 
for output, returncode in pool.imap_unordered(process, zip(children, params)): 
    if returncode == 0: 
     print("Got %r" % output) 

Чем меньше ребенок спит, тем быстрее его результат доступен для родителей, независимо от первоначального заказа.

Без зомби и он не будет заторможен, если вход/выход превышают буферы труб.

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