【发布时间】:2022-08-19 01:07:15
【问题描述】:
我有一个程序,我必须从网络中提取文件(p4 print 从版本控制服务器中提取文件并打印到标准输出)。因为网络和 IO 是最大的瓶颈,我正在尝试使用 asyncio。我尝试使用标准的 asyncio.subprocess.PIPE,但因为我有多个子进程,我不断遇到死锁。我想尝试的解决方案是创建一个新文件并将标准输出写入那里。
这是我得到的一些错误
尝试 2:错误 \"OSError: [Errno 9] Bad file descriptor\"
async def _subprocess_wrapper(self, path):
async with self.sem:
_, write = os.pipe()
proc = await asyncio.create_subprocess_exec(
\'p4\', \'print\', \'-q\', path,
stdout=write,
stderr=write
)
status = await proc.wait()
file = os.fdopen(write, \'r\')
txt = file.read()
os.close(write)
os.close(_)
return status, txt
尝试 3:错误 \"AttributeError: \'NoneType\' 对象没有属性 \'read\'\"
async def _subprocess_wrapper(self, path):
async with self.sem:
_, write = os.pipe()
proc = await asyncio.create_subprocess_exec(
\'p4\', \'print\', \'-q\', path,
stdout=write,
stderr=write
)
status = await proc.wait()
if status != 0:
txt = await proc.stderr.read()
else:
txt = await proc.stdout.read()
os.close(write)
os.close(_)
return status, txt.decode()
任何帮助,将不胜感激
-
我强烈建议返回标准 asyncio 并尝试识别和修复死锁。在 asyncio 中,所有 I/O 都必须是非阻塞的或由事件循环管理。该循环使用 select(或 poll)来识别准备好读/写的文件描述符(网络套接字、管道),并在这些 FD 和缓冲区之间传输数据。执行
await的I/O 应用程序代码与这些数据缓冲区交互,而不是与描述符交互。像您尝试做的那样使用直接管道 I/O 根本不适合 asyncio。
标签: python subprocess python-asyncio