Python的协程

本文最后更新于 2026年5月30日

未完待续

1.协程

协程(coroutine),又叫微线程或虚拟线程,是一种用户态的上下文切换技术,python中的协程,是通过一种可以被挂起,并且挂起后还能恢复执行的函数来实现的

某些操作会造成当前线程CPU发生阻塞,比如I/O操作,I/O操作不需要当前线程执行,但是当前线程提交了操作后也要白白等待一段时间拿到数据,才能继续执行,之前可以使用多线程来同时进行多路I/O操作,让子线程阻塞,主线程干些别的,而协程可以实现的就是让单个线程进行多路I/O操作时,也可以不需等待。

python中,协程可将多路I/O操作拆为多个方法,每个方法执行一路,事件循环实时监测各个方法状态,哪个方法阻塞了,事件循环迅速切换其他不阻塞的方法继续执行,而且这一切都发生在一个线程内。

2.async和协程函数

在python中,将一个普通函数加上async关键字,就会变成一个协程函数,执行协程函数,函数本身不会被调用,而是直接返回一个协程(coroutine )对象

async def a():
    print('a')
    return 1

async def b():
    print('b')
    return 2

task1 = a()
task2 = b()

if __name__ == "__main__":
    print(task1)
    print(task2)
<coroutine object a at 0x000001D4A91E5A80>
<coroutine object b at 0x000001D4A91E59C0>
<sys>:0: RuntimeWarning: coroutine 'a' was never awaited
<sys>:0: RuntimeWarning: coroutine 'b' was never awaited

3.asyncio和事件循环

要使得协程函数执行,需要asyncio.run()来调用协程函数,asyncio的原理,是将协程函数包装成任务,交给事件循环,事件循环就是一个死循环,不断轮询检查管理的协程函数的状态,发现谁阻塞了,立即将执行权拿走,交给其他未阻塞的协程函数继续执行当前线程

协程函数的返回值,也是从asyncio.run()的调用拿到

import asyncio

async def a():
    print('a')
    return 1

task1 = a()

if __name__ == "__main__":
    r = asyncio.run(task1)
    print(r)
a
1
<sys>:0: RuntimeWarning: coroutine 'b' was never awaited

4.await关键字

await对于python协程非常重要,关系着协程是否真正实现

事件循环基于await判断程序是否阻塞,遇到await,CPU控制权便交给了事件循环,事件循环会执行await后面的代码,同时事件循环也会认定await后面的代码是阻塞执行,将执行权拿走,交给其他未阻塞的协程函数继续执行当前线程(如果有的话)

如果协程函数中没有await,事件循环永远不会得到CPU控制权,当前函数一直执行下去,即使真的执行阻塞代码,其他未阻塞的协程函数也不会得到执行权

import time

def a():
    print('a')
    time.sleep(5)
    print('after a')

def b():
    print('b')
    time.sleep(5)
    print('after b')

def c():
    print('c')

# 4. 测试任务执行函数,模拟client端
def sync_tasks():
    a()
    b()
    c()

if __name__ == "__main__":
    sync_tasks()
import asyncio

async def a():
    print('a')
    await asyncio.sleep(5)
    print('after a')

async def b():
    print('b')
    await asyncio.sleep(5)
    print('after b')

async def c():
    print('c')

# 4. 测试任务执行函数,模拟client端
async def tasks():
    task1 = asyncio.create_task(a())
    task2 = asyncio.create_task(b())
    await task1
    await task2


if __name__ == "__main__":
    asyncio.run( tasks() )

5.python不存在协程


"如果文章对您有帮助,可以请作者喝杯咖啡吗?"

微信二维码

微信支付

支付宝二维码

支付宝


Python的协程
https://blog.liuzijian.com/post/2026/03/22/python-coroutine/
作者
Liu Zijian
发布于
2026年3月22日
更新于
2026年5月30日
许可协议