Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python asyncio子进程连续写入stdin和读取stdout/stderr_Python_Python 3.x_Subprocess_Python Asyncio - Fatal编程技术网

Python asyncio子进程连续写入stdin和读取stdout/stderr

Python asyncio子进程连续写入stdin和读取stdout/stderr,python,python-3.x,subprocess,python-asyncio,Python,Python 3.x,Subprocess,Python Asyncio,我目前正在执行python3 asyncio中的子进程任务。我的代码只需同时写入stdin和读取stdout/stderr即可: 导入异步IO 异步def读取标准输出(标准输出): 打印('read_stdout') 尽管如此: buf=等待标准读取(10) 如果不是buf: 打破 打印(f'stdout:{buf}') 异步def read_stderr(stderr): 打印('read_stderr') 尽管如此: buf=wait stderr.read() 如果不是buf: 打破 打印

我目前正在执行python3 asyncio中的子进程任务。我的代码只需同时写入stdin和读取stdout/stderr即可:

导入异步IO
异步def读取标准输出(标准输出):
打印('read_stdout')
尽管如此:
buf=等待标准读取(10)
如果不是buf:
打破
打印(f'stdout:{buf}')
异步def read_stderr(stderr):
打印('read_stderr')
尽管如此:
buf=wait stderr.read()
如果不是buf:
打破
打印(f'stderr:{buf}')
异步def写入标准数据(标准数据):
打印('write_stdin')
对于范围(100)内的i:
buf=f'line:{i}\n'.encode()
打印(f'stdin:{buf}')
标准写入(buf)
等待标准排水管()
等待异步睡眠(0.5)
异步def run():
proc=wait asyncio.create_subprocess_exec(
“/usr/bin/tee”,
stdin=asyncio.subprocess.PIPE,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE)
等待asyncio.gather(
读取标准(程序标准),
读标准(程序标准),
写入标准(过程标准))
asyncio.run(run())
它工作得很好,但我看到一个警告:

Warning
使用
communicate()
方法,而不是
process.stdin.write()
wait process.stdout.read()
wait process.stderr.read
。这避免了由于流暂停读取或写入以及阻塞子进程而导致的死锁

这是否意味着上述代码在某些情况下会陷入死锁?如果是这样,如何在python3 asyncio中连续写入
stdin
和读取
stdout
/
stderr
,而不出现死锁


非常感谢。

警告来自子流程模块,警告不要使用幼稚的代码,这些代码试图实现看似完全正确的简单通信,例如:

# write the request to the subprocess
await proc.stdin.write(request)
# read the response
response = await proc.stdout.readline()
如果子进程在读取整个请求之前就开始写入响应,这可能会导致死锁。如果响应足够大,子进程将阻塞,等待父进程读取部分响应并在管道缓冲区中腾出空间。但是,父级无法执行此操作,因为它仍在写入响应,并等待写入完成后再开始读取。因此,子级等待父级读取(部分)响应,父级等待子级完成接受请求。由于双方都在等待另一方的当前操作完成,因此这是一个死锁


您的代码没有这个问题,因为您的读写是并行执行的。因为读者从不等待作者,反之亦然,所以没有机会出现(那种)僵局。如果您查看一下
通信的方式,您会发现,除了一些调试日志记录之外,它的工作原理与您的代码非常相似。

通信
等待子进程终止。如果您希望多次阅读(例如,阅读内容、回复stdin、再次阅读等),则
通信
根本无法使用。警告只涉及一次读取的简单情况…感谢您的回复,因此反复读取/写入不会有问题?非常感谢您提供非常详细的答案!