python asyncio原理_Asyncio 源码分析

本文详细探讨了Python中的协程和asyncio框架,解释了协程为何比线程更轻量级,并通过源码分析阐述了asyncio如何利用epoll等事件机制实现协程调度。通过示例展示了asyncio任务的运行流程,包括run函数的内部工作、事件循环的调度策略以及Task类中的关键方法__step。文章强调理解asyncio原理对于解决使用中遇到的问题和自定义异步库的重要性。
摘要由CSDN通过智能技术生成

python 中的协程

从我个人的理解来说一说 python中的协程,我们知道 linux 中的线程比进程轻量级,切换成本低,协程比线程更轻量级。所以切换成本耕地,是基于生成器来实现的也就是 yield 语句,后来又有 yeild from 子协程的语法出现,生成器是迭代器,迭代器不是生成器,生成器能够输出值,也可以接收值,可以 hang/resume。当然在 python3.5 使用了新的语法 async/await, 本质没啥变化,仅仅是防止在语法上的混淆。可以进行隐式切换或者显式切换,在一个线程中实现多协程切换,asyncio 就是显式的来切换协程。

Asyncio 异步框架

asyncio 框架是建立在 epoll、poll、seledct等功能基之上的,下文统一用 epoll 代替,当然使用那种事件机制取决于操作系统,在使用asyncio时,大部分操作是用asyncio运行任务,运行任务时 asyncio 并没有使用epoll 机制,因为我们知道 epoll 是需要注册文件描述符的,是在使用协程,至于协程和 epoll 怎么结合运行的,下文会细说。epoll 是用来实现异步 web 框架用的。协程使用来运行用户的 task。

Asyncio 的运行流程

简单写一个异步任务,这个任务简单点,因为本篇文章主要讲的是 asyncio 的运行机制而不是 asyncio 的使用

import asyncio

async def print_hello_after3second():

await asyncio.sleep(3)

print("hello")

asyncio.run(print_hello_after3second)

这里使用的 run 这个接口,使用 asyncio 运行异步任务有很多种方式,run 我觉得更像是一个命令行,从外面看接口简单,其实内部帮忙做了很多事情.为了节省篇幅以及使得文章看起来清晰每个代码片段只截取重要部分,其余的省略。

asyncio/runners.py

#run 第一个参数要是个协程

def run(main, *, debug=False):

# loop 理解成 epoll 就好

events.set_event_loop(loop)

#重点在这里

loop.run_until_complete(loop.shutdown_asyncgens())

....

asyncio/base_events.py

def run_until_complete(self, future):

....

# asyncio 会把我们传进来的任务封装成 task,也可以说是 future,task 是 future 的子类

future = tasks.ensure_future(future, loop=self

# 里面有 _run_once 是用来调度事件循环的

self.run_forever()

....

asyncio/task.py

# ensure_future 也是一个传递任务的接口

def ensure_future(coro_or_future, *, loop=None):

....

# 在调用 Task 类中的__init__方法进行初始化,同时将 Task 类中的 _step方法作为回掉函数注册到了事件循环中

task = loop.create_task(coro_or_future)

....

asyncio/base_events.py

#这个方法很重要所以在这里全部列出,里面包含了asyncio的调用思想,调度 task 和 epoll

def _run_once(self):

"""Run one full iteration of the event loop.

This calls all currently ready callbacks, polls for I/O,

schedules the resulting callbacks, and finally schedules

'call_later' callbacks.

"""

print("run once")

sched_count = len(self._scheduled)

if (s

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值