【问题标题】:Execute two functions concurrently using asyncio使用 asyncio 同时执行两个函数
【发布时间】:2020-02-02 07:58:26
【问题描述】:

我目前有一个设置,我打开一个子进程,我必须同时读取 stdoutstderr ,所以在调用子进程后我为 @ 生成了一个新线程987654323@ 并在主线程中处理stderr

# imports
from subprocess import Popen, PIPE
from threading import Thread


def handle_stdout(stdout):
    # ... do something with stdout,
    # not relevant to the question
    pass


def my_fn():
    proc = Popen([...], stdout=PIPE, stderr=PIPE)
    Thread(target=lambda: handle_stdout(proc.stdout)).start()
    # ... handle stderr
    print(proc.stderr.read())
    proc.wait()
    proc.kill()

my_fn()

有没有一种方法可以使用 asyncio 实现相同的目标?

【问题讨论】:

    标签: python python-3.x async-await python-asyncio


    【解决方案1】:

    您的代码的无线程asyncio 版本可能如下所示:

    import asyncio
    import asyncio.subprocess
    
    async def handle_stdout(stdout):
        while True:
            line = await stdout.readline()  # Possibly adding .decode() to get str
            if not line:
                break
        # In 3.8 four lines above can be replaced with just:
        # while line := await stdout.readline():  # Yay walrus operator!
            # ... do stuff with line ...
    
    async def my_fn():
        # Note: No list wrapping on command line arguments; all positional arguments are part of the command
        proc = await asyncio.create_subprocess_exec(..., stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE)
        stdout_task = asyncio.create_task(handle_stdout(proc.stdout))
        # ... handle stderr
        print(await proc.stderr.read())
        await stdout_task
        await proc.wait()
    
    if  __name__ == '__main__':
        asyncio.run(my_fn())
    

    API 有点不同,异步函数实际上是在您从它们创建任务时调用的(线程必须接受未调用的函数),您需要小心await 采取的所有异步操作,但它不是 不同。主要问题是async 的病毒性质;因为你只能在async 函数中使用await,所以很难从非异步代码中调用异步代码(反之亦然,只要非异步代码不会因任何原因阻塞)。它使异步代码库在很大程度上与非async 的东西不兼容,并且几乎不可能进行零散转换,但对于全新的代码,它可以正常工作。

    【讨论】:

    • 我认为它是await asyncio.create_subprocess_exec(),但按预期工作
    • @Fr3ddyDev:是的,这是未经测试就完成的,你会想要await
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    • 2016-09-27
    • 1970-01-01
    • 2022-12-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多