python协程的调度基于事件循环而非线程切换。事件循环作为核心协调器,监听i/o事件并管理协程执行。当协程遇到i/o阻塞时,通过await交出控制权,事件循环据此调度其他任务。i/o就绪后,事件循环恢复相应协程,实现非阻塞并发。底层依赖生成器机制与i/o多路复用技术(如epoll),协程切换仅在用户态保存少量状态,效率远高于线程。然而,协程无法处理cpu密集型任务,需协程自身主动交出控制权,否则将阻塞整个事件循环。理解生成器(yield/yield from)与事件循环机制,是掌握python协程调度的关键。

Python协程的调度核心在于事件循环(Event Loop),它像一个中央协调器,不断监听各种I/O事件和任务状态,当一个协程遇到阻塞操作时,它会将控制权交还给事件循环,事件循环则会去执行其他就绪的协程或处理其他事件,待之前的阻塞操作完成后,再将控制权交还给对应的协程,从而实现非阻塞的并发。这种切换并非真正的线程上下文切换,而是基于生成器的暂停与恢复机制,由Python运行时在用户态完成。

要深入理解Python协程调度,我们得从它的底层逻辑——或者说,它如何“欺骗”操作系统和开发者——来切入。核心在于,Python的协程(特指
asyncio
await
事件循环拿到控制权后,并不会傻傻地等着。它会去检查所有已注册的任务(也就是那些正在等待或已准备好执行的协程),看看有没有哪个任务已经就绪。这个检查过程依赖于底层的I/O多路复用技术,比如Linux上的
epoll
kqueue
IOCP
立即学习“Python免费学习笔记(深入)”;

一旦某个I/O事件就绪(比如网络数据包到达),事件循环就会找到对应的协程,并将其标记为“可运行”。然后,它会选择下一个可运行的协程来恢复执行。这个恢复过程,本质上是调用生成器的
send()
await
await
Python的协程并非凭空出现,它的思想根植于Python的生成器(generators)。最初,我们可以利用生成器的
yield
yield
send()
yield from
async/await
yield from
async/await

然而,直接使用生成器来构建异步程序,代码会显得比较晦涩,可读性也不佳,尤其是在处理异常和取消操作时更是如此。Python 3.5引入的
async
await
async def
await
await
async def
coroutine
await
__await__
如果说协程是舞台上的演员,那事件循环就是导演,而I/O多路复用技术则是导演手中的对讲机,让它能同时关注多个演员的状态。在Python的
asyncio
SelectorEventLoop
_UnixSelectorEventLoop
select
poll
epoll
kqueue
这些系统调用的强大之处在于,它们允许一个进程同时监听多个I/O事件(例如,多个socket连接的读写就绪)。事件循环启动后,它会进入一个无限循环,调用这些多路复用函数,阻塞在那里,直到有I/O事件发生或者达到设定的超时时间。一旦有事件就绪(比如,客户端发来了数据,或者服务器可以发送数据了),多路复用函数就会返回,并告知事件循环是哪个文件描述符发生了什么事件。
事件循环拿到这些信息后,会根据之前注册的回调(通常是对应的协程任务),将控制权交还给相关的协程。举个例子,当一个协程执行
await reader.read()
epoll
await
协程的“切换”并非操作系统层面的上下文切换,而是一种用户态的协作式调度。理解这一点,是理解Python协程效率的关键。当一个协程遇到
await
yield
yield from
具体来说,
async def
coroutine
await
coroutine
send(None)
await
await
yield
Future
Task
这个“冻结”和“恢复”的过程,就是协程的上下文管理。Python解释器会保存协程的当前栈帧状态,以便在它被唤醒时能够准确无误地从上次暂停的地方继续执行。这与线程的上下文切换不同,线程切换需要保存和恢复完整的CPU寄存器、程序计数器、栈指针等,并涉及内核态的介入,开销较大。而协程的切换,仅仅是保存和恢复少量与生成器状态相关的Python对象,完全在用户态完成,因此其开销极小,这也是协程能够支持高并发任务的关键原因之一。
举个不那么严谨但形象的例子:线程切换就像两个人同时在用一台电脑,需要频繁地保存和加载各自的桌面环境;而协程切换则像一个人在写多个剧本,写到某个地方卡住了,就放下笔去写另一个,等有灵感了再回来接着写。这个过程中,他只需要记住上次写到哪了,而不需要重新“启动”整个大脑。这种轻量级的切换,正是Python协程高效的秘密。
以上就是Python源码如何实现协程调度机制 探究事件循环设计与切换逻辑的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号