我当前正在使用Python3的asyncio模块执行subprocess任务。我的代码简单地向标准输入(stdin)写入内容,并同时读取标准输出(stdout)和标准错误(stderr):
import asyncio
async def read_stdout(stdout):
print('read_stdout')
while True:
buf = await stdout.read(10)
if not buf:
break
print(f'stdout: { buf }')
async def read_stderr(stderr):
print('read_stderr')
while True:
buf = await stderr.read()
if not buf:
break
print(f'stderr: { buf }')
async def write_stdin(stdin):
print('write_stdin')
for i in range(100):
buf = f'line: { i }\n'.encode()
print(f'stdin: { buf }')
stdin.write(buf)
await stdin.drain()
await asyncio.sleep(0.5)
async def run():
proc = await asyncio.create_subprocess_exec(
'/usr/bin/tee',
stdin=asyncio.subprocess.PIPE,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE)
await asyncio.gather(
read_stderr(proc.stderr),
read_stdout(proc.stdout),
write_stdin(proc.stdin))
asyncio.run(run())
它的工作效果相当不错,但我在Python3文档页面上看到了一个警告:
警告
使用communicate()
方法而不是process.stdin.write()
,await process.stdout.read()
或await process.stderr.read
,以避免由于流暂停读取或写入而导致死锁并阻塞子进程。
这是否意味着以上代码会在某些情况下陷入死锁?如果是这样,如何在Python3 asyncio中连续编写stdin并读取stdout / stderr而不出现死锁?
非常感谢。
communicate
等待子进程终止。如果您期望多次读取(例如,读取一些内容,向 stdin 写入回复,再次读取等),则communicate
无法使用。警告仅涉及一次性读取的简单情况... - Bakuriu