I need to launch a subprocess and enable two threads for reading its stdout
and stderr
respectively.
The following code is just considering stdout
:
def reader(rfd):
while True:
try:
data = os.read(rfd, bufsize)
except OSError:
break
else:
chomp(data)
rout, wout = os.pipe()
tout = threading.Thread(target=reader, args=(rout,))
tout.start()
subprocess.check_call(command, bufsize=bufsize, stdout=wout, stderr=werr)
os.close(wout)
os.close(rout)
tout.join()
The code works, except I noticed that not all data is processed, as if the os.close(wout)
function kills the reader before all data is read. On the other hand, if I don't close wout
my process will be hanging forever on tout.join()
.
I can tell this is a buffering problem because if I put a very bad time.sleep(0.1)
just after subprocess.check_call(...)
everything magically works.
The good way would be flushing instead of waiting, but any call to os.fsync()
over a pipe is giving OSError: [Errno 22] Invalid argument
.
Any hint about how to flush a pipe created with os.pipe
?