【发布时间】:2019-08-30 16:03:26
【问题描述】:
我目前正在执行 python3 asyncio 中的子进程任务。我的代码只是写入标准输入并同时读取标准输出/标准错误:
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 document page 上看到了警告:
Warning使用communicate()方法而不是process.stdin.write()、await process.stdout.read()或await process.stderr.read。这避免了由于流暂停读取或写入并阻塞子进程而导致的死锁。
这是否意味着上面的代码在某些情况下会陷入死锁?如果是这样,如何在python3 asyncio中连续写入stdin和读取stdout/stderr而不会出现死锁?
非常感谢。
【问题讨论】:
-
communicate等待子进程终止。如果您希望阅读多次(例如阅读某些内容、向标准输入写回复、再次阅读等),那么communicate根本无法使用。该警告仅涉及一次性读取的简单情况... -
谢谢您的回复,这样反复读/写就没有问题了吗?
标签: python python-3.x subprocess python-asyncio