Sep-27-2020, 07:09 AM
(This post was last modified: Sep-27-2020, 07:10 AM by Gribouillis.)
Here is a solution using socket pairs instead of pipes. The advantage is that there are less blocking issues. Avoiding blocking with pipes may involve using threads and queues to read in the pipe, so I like the option to set sockets unblocking.
The below example shows a program main.py that starts two subprocesses a.py and b.py, both sending their output to the same socket.
The below example shows a program main.py that starts two subprocesses a.py and b.py, both sending their output to the same socket.
# main.py import subprocess as sp import socket import time def main(): print('Starting') r, w = socket.socketpair() r.settimeout(0.2) r.shutdown(socket.SHUT_WR) w.shutdown(socket.SHUT_RD) a = sp.Popen(['python3', 'a.py'], stdout=w) b = sp.Popen(['python3', 'b.py'], stdout=w) procs = [a, b] while procs: try: x = r.recv(1024) print('Read:', repr(x)) except socket.timeout: print('Timed out!') procs = [p for p in procs if p.poll() is None] r.close() w.close() print('Bye') if __name__ == '__main__': main()
# a.py from time import sleep import sys for i in range(5): print(i) sys.stdout.flush() sleep(0.5)
# b.py from time import sleep import sys for i in 'abcdef': print(i) sys.stdout.flush() sleep(0.3)
Output:λ python3 main.py
Starting
Read: b'a\n'
Read: b'0\n'
Timed out!
Read: b'b\n'
Timed out!
Read: b'1\n'
Read: b'c\n'
Timed out!
Read: b'd\n'
Read: b'2\n'
Timed out!
Read: b'e\n'
Timed out!
Read: b'3\nf\n'
Timed out!
Timed out!
Read: b'4\n'
Timed out!
Timed out!
Timed out!
Bye
You could do something similar by using r, w = os.pipe()
instead of r, w = socket.socketpair()
but then you have to manage the blocking problem when you try to read in r.