Python异步编程使用asycnawait两个关键词进行修饰。其中asycn关键词修饰过程,而await修饰操作本身。

EventLoop(事件循环)

Python异步编程的核心是维护若干个事件循环,学过操作系统的可以把事件简单地认为是“进程”。Python的事件循环维护若干个Task(协程),当Task被阻塞或者Task完成了,就从Task池(我起的名字)中获取下一个可以用的Task来执行。你可以通过get_running_loop()get_event_loop()来获取当前的事件循环。区别是前者如果没有正在运行的事件循环则会引发 RuntimeError并且只能由协程或回调来调用。后者如果没有正在运行的事件循环择新建一个事件循环。

Task

事件循环本质就是管理Task。Task是一次协程的一次执行。协程使用asycn关键词进行修饰。这种函数最大特点是执行可以暂停,交出执行权。在asycn修饰的函数里面可以加上await修饰的asycn函数,就像这样:

1
2
3
4
5
6
7
8
9
import asyncio

async def get_data()
return 11

async def main():
# get_data()
d = await get_data()
print(d)

当执行到await这一步的时候,就暂停当前Task命令的执行,反而去执行别的命令(就相当于阻塞)。这个时候会有人问,await修饰的那段任务执行情况是怎么样的呢,是作为一个新的Task放入事件循环中?其实不是,await代表异步执行,你可以简单地理解成开一个新的协程去做这件事情。这个协程首先把当前Task给暂停了,换一个新的Task。等那个新的协程把事情做完了,把之前那个被暂停的Task抓到Task池里面。其核心就是把IO密集型的任务进行重组,在IO等待的时候做点别的。

那至于Python如何平衡这个协程和新协程,就是内核做的事情,程序员不需要思考这件事。你可以认为,在程序员的角度中,就是做到需要等待的任务,就交给别人先占用CPU,我等完了我再来占用CPU。异步的目的就是并发执行。并发执行计算和IO,并发执行若干个任务。(这里我猜有一种机制,可以让计算,也就是CPU操作和IO一起执行,其实硬件上是可以实现的,有一种叫做DMA的机器可以实现IO和计算分离,具体的实现可以去学学,但是我目前就只知道用法)

Push task to eventloop

我们可以使用asyncio.run()来执行一个异步任务,也可以使用asyncio.gather()打包若干个Task进行执行。

Get the return value from task

我们可以使用task.result()来统一返回,可以配合barrier一起使用

1
2
3
4
5
6
7
8
9
10
11
if __name__ == '__main__':

start_time = time.time()#程序启动时间

loop = asyncio.get_event_loop()#获取本机事件循环
tasks = [loop.create_task(get_data(i)) for i in range(4)]

loop.run_until_complete(asyncio.wait(tasks))
print()
for task in tasks:
print(task.result())
更新于

请我喝[茶]~( ̄▽ ̄)~*

Sukuna 微信支付

微信支付

Sukuna 支付宝

支付宝