2016-02-15 2 views
1

Я прочитал вопрос/ответ/комментарии на Non-blocking read on a subprocess.PIPE in python, но мне было немного не хватает.Неблокирующее чтение на подпроцессе.PIPE в python

Когда я внедрил предоставленное решение, я заметил, что этот подход работает лучше всего, когда субпроцесс заканчивается на его собственном. Но если подпроцесс предоставляет поток информации, и мы ищем одно совпадение вывода, то этот подход не работает для моих нужд (особенно для Windows, если это имеет значение).

Вот мой пример: ping.py

import time 

def main(): 
    for x in range(100): 
     print x 
     time.sleep(1) 

if __name__ == '__main__': 
    print("Starting") 
    time.sleep(2) 
    main() 

runner.py

import subprocess 
import time 
import sys 
from Queue import Queue, Empty 
from threading import Thread 

def enqueue_output(out, queue): 
    for line in iter(out.readline, b''): 
     queue.put(line) 
    out.close() 

#Start process we want to listen to 
pPing = subprocess.Popen('ping.py', 
    shell=True, 
    stdin=subprocess.PIPE, 
    stdout=subprocess.PIPE, 
    ) 

q = Queue() 
t = Thread(target=enqueue_output, args=(pPing.stdout, q)) 
t.daemon = True 
t.start() 

#make sure it's started 
print ("get the first line") 
try: 
    line = q.get() 
except Empty: 
    pass 
else: 
    print line.strip() 

#look for the 'magic' output 
print("empty the queue") 
while not q.empty(): 
    line = q.get_nowait().strip() 
    if (line == "3"): 
     print("got it!") 
     sys.exit() 
    else: 
     print("not yet") 

Я ожидаю, что бегун будет убедиться, что запущен процесс, а затем ждать волшебного выхода а затем остановится, что и будет. Однако чем дольше работает подпроцесс, тем дольше бежит бегун. Но так как выход «magic» поступает относительно быстро, мне нужно подождать, пока не завершится подпроцесс, прежде чем я получу что-нибудь обработанное.

Что мне не хватает?

Спасибо, Роберт

+0

'pPing.kill()' после того, как вы получите магию, может помочь. – tdelaney

+0

.... затем 'pPing.wait()', чтобы убедиться, что процесс зомби уходит. – tdelaney

ответ

0

Хорошо, если я правильно понимаю, что вы пытаетесь сделать, проблема с пинг-прежнему является процессом ребенка бегуна. Хотя вы можете сделать чтение неблокируемым, но родительский процесс фактически не будет завершен, пока ребенок все еще работает. Если вы хотите, чтобы бегун не дождался, пока ребенок закончит, прочитайте первую строку и первый магический выход, а затем выйдите, вам нужно выполнить ping, чтобы отключиться от родительского процесса. Посмотрите на этот пример кода, чтобы посмотреть, как это делается. http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/. Конечно, вы можете пропустить часть, где они закрываются и снова открывать все потоки ввода-вывода.

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

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