multithreading - How can Python continuously fill multiple threads of subprocess? -
i'm running app, foo, on linux. bash script/terminal prompt, application runs multi-threaded command:
$ foo -config x.ini -threads 4 < inputfile
system monitor , top report foo averages 380% cpu load (quad-core machine). i've recreated functionality in python 2.6x with:
proc = subprocess.popen("foo -config x.ini -threads 4", \ shell=true, stdin=subprocess.pipe, \ stdout=subprocess.pipe, stderr=subprocess.pipe) mylist = ['this','is','my','test','app','.'] line in mylist: txterr = '' proc.stdin.write(line.strip()+'\n') while not proc.poll() , not txterr.count('finished'): txterr += subproc.stderr.readline() print proc.stdout.readline().strip(),
foo runs slower , top reports cpu load of 100%. foo runs fine shell=false, still slow:
proc = subprocess.popen("foo -config x.ini -threads 4".split(), \ shell=false, stdin=subprocess.pipe, \ stdout=subprocess.pipe, stderr=subprocess.pipe)
is there way have python subprocess continuously fill threads?
if python script doesn't feed foo
process fast enough offload reading stdout, stderr threads:
from queue import empty, queue subprocess import pipe, popen threading import thread def start_thread(target, *args): t = thread(target=target, args=args) t.daemon = true t.start() return t def signal_completion(queue, stderr): line in iter(stderr.readline, ''): if 'finished' in line: queue.put(1) # signal completion stderr.close() def print_stdout(q, stdout): """print stdout upon receiving signal.""" text = [] line in iter(stdout.readline, ''): if not q.empty(): try: q.get_nowait() except empty: text.append(line) # queue empty else: # received completion signal print ''.join(text), text = [] q.task_done() else: # buffer stdout until task finished text.append(line) stdout.close() if text: print ''.join(text), # print rest unconditionally queue = queue() proc = popen("foo -config x.ini -threads 4".split(), bufsize=1, stdin=pipe, stdout=pipe, stderr=pipe) threads = [start_thread(print_stdout, queue, proc.stdout)] threads += [start_thread(signal_completion, queue, proc.stderr)] mylist = ['this','is','my','test','app','.'] line in mylist: proc.stdin.write(line.strip()+'\n') proc.stdin.close() proc.wait() t in threads: t.join() # wait stdout
Comments
Post a Comment