2017-09-16 15 views
0

파이썬에서 서브 프로세스를 사용하여 stdout을 리디렉션 할 때 처리 속도가 매우 느려집니다. 내가 잘못하고 있니?파이썬에서 서브 프로세스로 stdout을 리디렉션하는 것은 매우 느립니다.

기본적으로 외부 프로그램의 표준 출력을 파이프하여 대기열에 넣습니다. 그런 다음 다른 기능에서 콘솔에 인쇄합니다.

from subprocess import Popen, PIPE 
from queue import Queue 
import sys 
from threading import Thread, Event 
import threading 

class Buffer(Queue): 

    def __init__(self, *args, **kwargs): 
     Queue.__init__(self, *args, **kwargs) 

    def write(self, line): 
     self.put_nowait(line) 
     self.join() 

    def read(self): 
     element = self.get_nowait() 
     self.task_done() 
     return element 

def write_output(buffer, stopped): 

    hexdump = Popen(['hexdump', '-C', '/dev/urandom'], stdout=PIPE) 
    while hexdump.returncode is None: 
     for line in hexdump.stdout.readlines(8192): 
      buffer.write(line) 
      if stopped.is_set(): 
       hexdump.terminate() 
       hexdump.wait() 
       print('process terminated.') 
       break 

def read_output(buffer, stopped): 
    while not stopped.is_set(): 
     while not buffer.empty(): 
      output = buffer.read() 
      print('********* output: {}'.format(output)) 
      sys.stdout.flush() 
    print('stopped') 
    sys.stdout.flush() 


buffer = Buffer() 
stopped = Event() 


generate_random_output = Thread(target=write_output, args=(buffer, stopped)) 
generate_random_output.name = 'generate_random_output' 
generate_random_output.start() 

process_output = Thread(target=read_output, args=(buffer, stopped)) 
process_output.name = 'process_output' 
process_output.start() 

try: 
    while True: 
     continue 
except KeyboardInterrupt: 
    stopped.set() 
    generate_random_output.join() 
    process_output.join() 
    print('finished generating') 
    print('finished processing') 

내가 어떤 도움을 주셔서 감사합니다 : 여기

은 16 진 덤프와 샘플 코드가 임의의 출력을 생성하는 것입니다.

답변

0

하는 대신 출력 대기열로 리디렉션의 - 직접 과정을 :

def write_output(buffer, stopped): 

    hexdump = Popen(['hexdump', '-C', '/dev/urandom'], stdout=PIPE) 
    while hexdump.poll() is None: 
     while not stopped.is_set(): 
      for line in iter(hexdump.stdout.readline, b''): 
       print('********* output: %s' % line.decode(), end='') 
       sys.stdout.flush() 

     hexdump.terminate() 
     hexdump.wait() 
     print('process terminated.') 
     break 
+0

감사합니다! 때로는 stdout이 중단되어 출력을 청크로 만들기 위해 8192를 추가하려고했지만이 방법을 다시 시도 할 것입니다. –