but I can't get the result (stdout) of my command...
ConnectedCommand
(the type returned by envoy.connect()
) doesn't seem to be ready. In particular, the command can deadlock if it receives/generates enough (depending on platform) input/output.
In addition to calling c.block()
that also works for alive processes; you could remove all references to the command and use del c
to reap the zombie. If subprocesses are not dead; they won't be reaped until a cleanup method is run on start of the next subprocess (it depends on the implementation).
If envoy.run()
capabilities are not enough for your task; you could use subprocess
module directly. For example, to pass input to several processes and collect corresponding results; you could use ThreadPool
and .communicate()
method:
#!/usr/bin/env python
from multiprocessing.pool import ThreadPool
from subprocess import Popen, PIPE
def process(child_input):
child, input = child_input # unpack arguments
return child.communicate(input)[0], child.returncode # get the result
# define input to be pass to subprocesses
params = b"a b c".split()
# start subprocesses (the command is just an example, use yours instead)
children = [Popen("( echo -n {0}; sleep {0}; cat )".format(len(params) - i),
shell=True, stdin=PIPE, stdout=PIPE)
for i in range(len(params))]
# use threads to wait for results in parallel
pool = ThreadPool(len(params))
for output, returncode in pool.imap_unordered(process, zip(children, params)):
if returncode == 0:
print("Got %r" % output)
The less child sleeps the sooner its result is available to the parent regardless of the original order.
No zombies and It won't deadlock if input/output exceed pipe buffers.