我试图找出如何以非阻塞方式简单地启动一些长时间运行的shell命令,并按照它们完成的顺序异步处理它们的输出,即使这是另一个订单而不是它们开始,使用Python 3.4中提供的asyncio python库并转发.
我找不到一个这样做的简单例子,即使在asyncio文档中也是如此,这似乎也是相当低级的.
使用get_lines()
协同程序,以异步方式获取shell命令输出并将协同程序传递给asyncio.as_completed()
,以按照它们完成的顺序获取结果:
#!/usr/bin/env python3.5 import asyncio import sys from asyncio.subprocess import PIPE, STDOUT async def get_lines(shell_command): p = await asyncio.create_subprocess_shell(shell_command, stdin=PIPE, stdout=PIPE, stderr=STDOUT) return (await p.communicate())[0].splitlines() async def main(): # get commands output concurrently coros = [get_lines('"{e}" -c "print({i:d}); import time; time.sleep({i:d})"' .format(i=i, e=sys.executable)) for i in reversed(range(5))] for f in asyncio.as_completed(coros): # print in the order they finish print(await f) if sys.platform.startswith('win'): loop = asyncio.ProactorEventLoop() # for subprocess' pipes on Windows asyncio.set_event_loop(loop) else: loop = asyncio.get_event_loop() loop.run_until_complete(main()) loop.close()