python - 异步执行Python subprocess.Popen with wait()

标签 python subprocess python-asyncio python-multithreading popen

我是 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 之后删除输入。
Popenp.wait() 确实强制同步执行,但它是以阻塞主线程为代价的。
没有 p.wait()Popen 不会阻止它,但会在 ffmpeg 完成其工作之前调用函数 2。

我想实现类似于 Javascript promises 或 async/await 构造的东西,如下所示:

async func1() {
    let response = await fetch('/api');
    let user = await response.json();
    return user;
}

func2(func1());

听起来像是一项微不足道的任务,但我在多线程、多处理和异步之间迷失了方向。
如何在不阻塞主线程的情况下让函数 2 等待函数 1 的输出?

最佳答案

要在 asyncio 程序中生成子进程,请使用 asyncio's subprocess primitives它提供了一个类似于 subprocess 的接口(interface),但公开了可等待的协程。

与您的 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(func2(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())

关于python - 异步执行Python subprocess.Popen with wait(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62967728/

相关文章:

python - Boto3 - 如何通过代理连接到 S3?

python - 将 pandas python 中的 bool 输出切换为字符串

python - 像命令行模拟器一样使用 python 子进程模块

python - 处理带空格的目录 Python subprocess.call()

Python asyncio : Queue. join() 仅在未引发异常时完成,为什么? (上下文:编写异步映射函数)

python - asyncio aiohttp 取消http请求轮询,返回结果

python - scikit-learn FeatureUnion 网格搜索特征子集

python - 下载 Dropbox 文件夹中的所有 .mp4 文件

python - GUI 中 python 程序的实时输出

Django channel Postgres InterfaceError : connection already closed