Python 3.4+Async programmingterm
asyncio.SubprocessProtocol
protocols and transports
The protocol for a child process: the callbacks pipe_data_received(fd, data) for stdout/stderr output, pipe_connection_lost() and process_exited().
Syntax
transport, protocol = await loop.subprocess_exec(ProtocolClass, program, *args)
Learners rarely need this layer: streams (asyncio.open_connection() and asyncio.start_server()) cover TCP, and asyncio.create_subprocess_exec() covers processes. Instead of a protocol, asyncio.create_subprocess_exec() with await proc.communicate() is almost always easier: the output arrives whole, with no sorting of which fd sent what. The protocol's trap: process_exited() may come before the last pipe output is read, so 'the process exited' does not mean 'all data has arrived'.
Examples
import asyncio
import sys
class Out(asyncio.SubprocessProtocol):
def __init__(self, done):
self.done = done
self.data = b''
def pipe_data_received(self, fd, data):
self.data += data
def connection_lost(self, exc):
self.done.set_result(True) # все каналы закрыты — вывод получен целиком
async def main():
loop = asyncio.get_running_loop()
done = loop.create_future()
transport, proto = await loop.subprocess_exec(
lambda: Out(done), sys.executable, '-c', 'print(6 * 7)', stdin=None)
await done
print(proto.data.strip(), transport.get_returncode()) # → b'42' 0
transport.close()
asyncio.run(main())
See also
Open in the full glossarydocs.python.orgReport an inaccuracy