Python 立即运行任务,然后等待

Python 立即运行任务,然后等待,python,python-asyncio,Python,Python Asyncio,我是Python新手,代码如下所示: import time import asyncio async def my_async_function(i): print("My function {}".format(i)) async def start(): requests = [] # Create multiple requests for i in range(5): print("Creating request #{}".for

我是Python新手,代码如下所示:

import time
import asyncio

async def my_async_function(i):
    print("My function {}".format(i))

async def start():
    requests = []

    # Create multiple requests
    for i in range(5):
        print("Creating request #{}".format(i))
        requests.append(my_async_function(i))

    # Do some additional work here
    print("Begin sleep")
    time.sleep(10)
    print("End sleep")

    # Wait for all requests to finish
    return await asyncio.gather(*requests)

asyncio.run(start())
无论“额外工作”需要多长时间,请求似乎只在“结束睡眠”之后运行。我猜
asyncio.gather
才是真正开始执行它们的地方。如何让请求(也称为
my_async_function()
)立即启动,执行其他工作,然后等待所有请求在最后完成

编辑: 根据Krumelur的评论和我自己的发现,我所寻找的结果如下:

import time
import asyncio
import random

async def my_async_function(i):
    print("Begin function {}".format(i))
    await asyncio.sleep(int(random.random() * 10))
    print("End function {}".format(i))

async def start():
    requests = []

    # Create multiple requests
    for i in range(10):
        print("Creating request #{}".format(i))
        requests.append(asyncio.create_task(my_async_function(i)))

    # Do some additional work here
    print("Begin sleep")
    await asyncio.sleep(5)
    print("End sleep")

    # Wait for all requests to finish
    return await asyncio.gather(*requests)

asyncio.run(start())
只有当my_async_函数和“附加工作”都是可等待的,这样事件循环才能为它们提供执行时间时,这才有效。您需要
create_task
(如果您知道它是一个协同程序)或
确保未来
(如果它可能是一个协同程序或未来)以允许请求立即运行,否则它们仍然只有在您
收集
时间时才会运行。sleep()是一个同步操作

您需要使用异步睡眠并等待它, 例如

其他异步代码将仅在当前任务产生时运行(即,通常在“等待”某些内容时)


使用异步代码意味着您必须随时随地使用异步。异步操作适用于I/O绑定的应用程序。如果“额外工作”主要是CPU受限的,那么最好使用线程(但要注意全局解释器锁!)

哦,那么如果我有任何同步代码,它会阻止异步代码并阻止它运行吗?我想它可以在后台生成一个线程,继续我的同步代码。换句话说,Python是带有事件循环的单线程还是类似的?因此在本练习中,我使用
time.sleep()
模拟了同步工作。如果我正在进行不可等待的处理(例如一些数学计算),该怎么办?我不能同时运行其他代码吗?是的。事件循环是单线程的,这在大多数语言中都是如此。有时您可以等待线程连接等,但在Python中还存在全局解释器锁,这意味着一次只有一个线程将运行Python代码(允许I/O),因此,如果您的数学操作快速转移到本机代码,那么它与使用async/await(只允许C模块释放GIL)没有什么不同(例如,重型NymPy操作)你可以使用线程。如果循环驻留在Python中,你就不能,你应该看看多处理模块,它生成并行Python运行时,并通过队列等共享原语进行同步。我认为你应该探索使用线程/进程池的替代方法。你说你是CPU受限的。HTTP请求几乎不需要任何CPU因此,您可能不会受到CPU的限制,以致于网络请求不足,但如果是这样,python中唯一的解决方案就是一个进程池。“futures”是一个很好的接口,请参阅
await asyncio.sleep(10)