You may need to use Popen.communicate() .
If you write a large amount of data to stdin, and during this the child process generates output to stdout, then there may be a problem when the stdout buffer for the child becomes full before all your stdin data is processed. The child process blocks writing to stdout (because you are not reading it), and you block writing to stdin.
Popen.communicate() can be used to write stdin and read stdout / stderr at the same time to avoid the previous problem.
Note: Popen.communicate() is only suitable when the input and output can fit into your memory (they are not too large).
Update: If you decide to hack threads, here is an example implementation of the parent and child processes, which you can adapt to suit your needs:
parent.py:
#!/usr/bin/env python2 import os import sys import subprocess import threading import Queue class MyStreamingSubprocess(object): def __init__(self, *argv): self.process = subprocess.Popen(argv, stdin=subprocess.PIPE, stdout=subprocess.PIPE) self.stdin_queue = Queue.Queue() self.stdout_queue = Queue.Queue() self.stdin_thread = threading.Thread(target=self._stdin_writer_thread) self.stdout_thread = threading.Thread(target=self._stdout_reader_thread) self.stdin_thread.start() self.stdout_thread.start() def process_item(self, item): self.stdin_queue.put(item) return self.stdout_queue.get() def terminate(self): self.stdin_queue.put(None) self.process.terminate() self.stdin_thread.join() self.stdout_thread.join() return self.process.wait() def _stdin_writer_thread(self): while 1: item = self.stdin_queue.get() if item is None:
child.py:
#!/usr/bin/env python2 import sys while 1: item = sys.stdin.readline() sys.stdout.write('Processed: ' + item)
Note: IOError handled in read / write streams to handle cases when a child process terminates / terminates / kills.
pasztorpisti
source share