Ngu*_*inh 4 python subprocess python-3.x python-asyncio
我目前正在使用python3 asyncio中的子流程执行任务。我的代码只是简单地写入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())
Run Code Online (Sandbox Code Playgroud)
它工作得很好,但是我在Python3文档页面上看到警告:
Warning使用communicate()方法而不是process.stdin.write(),await process.stdout.read()或await process.stderr.read。这样可以避免由于流暂停读取或写入以及阻塞子进程而导致的死锁。
这是否意味着上述代码在某些情况下会陷入僵局?如果是的话如何写stdin和读stdout/ stderr无僵局ASYNCIO连续python3?
非常感谢你。
该警告已从常规子过程模块中保留下来,并警告那些试图实施看起来完全正确的简单通信的幼稚代码,例如:
# write the request to the subprocess
await proc.stdin.write(request)
# read the response
response = await proc.stdout.readline()
Run Code Online (Sandbox Code Playgroud)
如果子进程在读取整个请求之前开始写响应,则可能导致死锁。如果响应足够大,则子进程将阻塞,等待父进程读取其中的一部分并在管道缓冲区中腾出空间。但是,父级无法这样做,因为它仍在写入响应并在开始读取之前等待写入完成。因此,子级等待父级读取(某些)响应,而父级则等待子级完成接受请求。由于双方都在等待对方当前的操作完成,因此这是一个僵局。
您的代码不仅仅因为您的读取和写入是并行执行的,所以就没有这个问题。由于读者从不等待作家,反之亦然,因此没有机会陷入那种僵局。如果你看一看如何communicate被实现的,你会发现,除了一些调试日志记录,它的工作原理非常像你的代码。
| 归档时间: |
|
| 查看次数: |
283 次 |
| 最近记录: |