python - Python subprocess.Popen 与 wait() 的异步执行
问题描述
我是 Python 异步概念的新手。但是我想顺序调用 2 个函数,这里的顺序很重要:
def func1():
p = subprocess.Popen('ffmpeg -i in.webm out.mp4')
p.wait()
def func2():
os.remove('in.webm')
func1()
func2()
函数 1 包含转换视频文件的子进程,函数 2 之后删除输入。
Popen
withp.wait()
确实强制同步执行,但它是以阻塞主线程为代价的。
Popen
withoutp.wait()
不会阻止它,但会在 ffmpeg 完成其工作之前调用函数 2。
我想实现类似于 Javascript 承诺或 async/await 结构的东西,如下所示:
async func1() {
let response = await fetch('/api');
let user = await response.json();
return user;
}
func2(func1());
听起来像是一项微不足道的任务,但我迷失在多线程、多处理和异步之间。
如何让函数 2 在不阻塞主线程的情况下等待函数 1 的输出?
解决方案
要在 asyncio 程序中生成子进程,请使用asyncio 的子进程原语,它提供类似于 的接口subprocess
,但暴露了可等待的协程。
您的 JavaScript 示例的等价物将是这样的:
async def main():
# Schedule func1() to run, but don't await it. (In JavaScript
# it would be enough to just call func1().)
asyncio.create_task(func1())
print('we get here immediately')
# Await something to keep the event loop spinning - without
# this, the program would exit at this point. In real code
# this would await an exit signal, server.wait_closed(), etc.
await asyncio.Event().wait()
async def func1():
# Like in JavaScript, await suspends the current function
# until a result is available.
res = await fetch('/api1', {})
userid = (await res.json()).id
asyncio.create_task(fun2(userid))
async def func2(userid):
res = await fetch('/api2', ...userid...)
func3((await res.json()).url)
def func3(url):
print('user photo', url)
asyncio.run(main())
推荐阅读
- uwp - UWP:MenuItem 中的复选框显示为空白
- cloudrail - CloudRail 对 OneDrive For Business 的支持
- c# - 如何在 C# 中设计并行 Web api?
- mysql - 一张桌子,而不是两张,有一些空列
- html - 在显示为 flex 时保持 div 中的图像填充并保持纵横比
- keras - LSTM 预测如何合并多个自相关
- css - 如何更改 primeNg 树中树节点图标的颜色?
- python - Python,允许将单个字符串和字符串列表传递给函数
- spring-boot - Spring Boot Gemfire 服务器配置
- python - Python - 在数字字符串(不是整数)列表中填充 0 - ZFILL