2017-09-16 3 views
0

Lorsque j'utilise un sous-processus en Python pour rediriger stdout, le débit est très lent. Est-ce que je le fais mal?La redirection de stdout avec sous-processus en python est très lente

Fondamentalement, je canalise la sortie standard d'un programme externe pour le mettre dans une file d'attente. Puis dans une autre fonction, je l'imprime dans la console.

Voici un exemple de code avec hexdump pour générer une sortie aléatoire:

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') 

Je serais reconnaissant de toute aide.

Répondre

0

Au lieu de rediriger votre sortie vers file d'attente - processus directement:

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

Merci! Parfois, stdout se bloque donc je voulais ajouter 8192 pour obtenir la sortie en morceaux, mais je vais essayer de nouveau de cette façon. –