2017-09-16 28 views
0

Pythonでサブプロセスを使用してstdoutをリダイレクトすると、処理速度が非常に遅くなります。私はそれを間違っているのですか?サブプロセスを使った標準出力のリダイレクトは非常に遅い

基本的には、外部プログラムの標準出力をパイプしてキューに入れます。次に別の機能では、私はそれをコンソールに印刷します。ここで

は、ランダムな出力を生成するために、hexdumpに対してのサンプルコードです:

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

私は任意の助けをいただければ幸いです。

答えて

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を追加したかったのですが、私はこの方法でやり直します。 –

関連する問題