![](/img/trans.png)
[英]How to create my own pipe in asyncio.create_subprocess_exec
[英]Connect two processes started with asyncio.subprocess.create_subprocess_exec()
當與老同學開始兩個過程subprocess.Popen()
API,我可以輕松連接標准出一個進程的標准在另一個進程中,創造了以同樣的方式作為管道在UNIX外殼連接與命令時會做|
:
from subprocess import Popen, PIPE
process_1 = Popen(['ls'], stdout = PIPE)
process_2 = Popen(['wc'], stdin = process_1.stdout)
process_1.wait()
process_2.wait()
從asyncio.subprocess.create_subprocess_exec()
使用異步API時,如何完成相同的工作? 這是我嘗試的:
from asyncio.events import get_event_loop
from asyncio.subprocess import PIPE, create_subprocess_exec
async def main():
process_1 = await create_subprocess_exec('ls', stdout = PIPE)
process_2 = await create_subprocess_exec('wc', stdin = process_1.stdout)
await process_1.wait()
await process_2.wait()
get_event_loop().run_until_complete(main())
但是對create_subprocess_exec()
的第二次調用抱怨傳遞給stdin
的參數沒有fileno
(這是真的):
Traceback (most recent call last):
File ".../test-async.py", line 11, in <module>
get_event_loop().run_until_complete(main())
[...]
File ".../test-async.py", line 6, in main
process_2 = await create_subprocess_exec('wc', stdin = process_1.stdout)
[...]
File "/opt/local/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/subprocess.py", line 1388, in _get_handles
p2cread = stdin.fileno()
AttributeError: 'StreamReader' object has no attribute 'fileno'
如何獲得與上述同步示例相同的結果?
在asyncio中, process.stdout實際上是StreamReader ,而不是文件對象。 可以通過process._transport._proc.stdout
訪問文件對象。 不幸的是,您將無法使用它,因為它已經在事件循環中注冊,以便提供流接口process.stdout
。
解決該問題的一種方法是創建自己的管道並將文件描述符傳遞給子進程:
async def main():
read, write = os.pipe()
process_1 = await create_subprocess_exec('ls', stdout=write)
os.close(write)
process_2 = await create_subprocess_exec('wc', stdin=read, stdout=PIPE)
os.close(read)
return await process_2.stdout.read()
請注意,一旦啟動第一個子流程,就應顯式關閉write
文件描述符(除非您使用subprocess.PIPE
否則它不會自動關閉)。 在read
文件描述符也需要被關閉,如解釋在這里 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.