前两章我们讲述了多进程、多线程并发编程相关,这章我们来学习下Python中的协程。
协程相比线程更轻量级,在编写网络相关程序时性能较好,能充分利用cpu,一个协程等待io时不会阻止其它协程的执行。
我们这里仍然以能说明问题为目的,不会把协程的方方面面都讲到,如果有问题欢迎评论交流。
假如我们需要*载下**10张图片,*载下**每张的时间是2秒,如果我们串行去*载下**,那*载下**完就至少需要20秒的时间,那如果用10个协程去*载下**呢?
如果我们用10个协程去*载下**,时间应该会远小于串行*载下**,约等于2秒。为了简单说明问题,这里我们不会真正去*载下**图片,我们用睡眠2秒来模拟*载下**任务,分别打印出*载下**前与*载下**后的时间。
一、用到的协程库
python中的协程主要由asyncio库封装,我们直接调用这个库来操作协程就可以了,另外还会用到两个语法糖:async、await
二、启动协程
启动协程有两种方式,一个是await coroutine,另一个是 asyncio.create_task,调用这两个中的其中一个就会执行协程的代码
三、实现代码
import asyncio
from datetime import datetime
async def sleep_and_print(co_id, seconds):
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
print(f"{now}: coroutine {co_id} start sleep")
await asyncio.sleep(seconds)
now = datetime.now().strftime("%Y-%m-%d %H:%m:%S")
print(f"{now}: coroutine {co_id} end sleep")
async def main():
await asyncio.gather(*[asyncio.create_task(sleep_and_print(i, 2)) for i in range(10)])
asyncio.run(main())
四、输出结果
2026-03-13T20:01:06+00:00: coroutine 0 start sleep
2026-03-13T20:01:06+00:00: coroutine 1 start sleep
2026-03-13T20:01:06+00:00: coroutine 2 start sleep
2026-03-13T20:01:06+00:00: coroutine 3 start sleep
2026-03-13T20:01:06+00:00: coroutine 4 start sleep
2026-03-13T20:01:06+00:00: coroutine 5 start sleep
2026-03-13T20:01:06+00:00: coroutine 6 start sleep
2026-03-13T20:01:06+00:00: coroutine 7 start sleep
2026-03-13T20:01:06+00:00: coroutine 8 start sleep
2026-03-13T20:01:06+00:00: coroutine 9 start sleep
2026-03-13T20:01:06+00:00: coroutine 0 end sleep
2026-03-13T20:01:06+00:00: coroutine 1 end sleep
2026-03-13T20:01:06+00:00: coroutine 2 end sleep
2026-03-13T20:01:06+00:00: coroutine 3 end sleep
2026-03-13T20:01:06+00:00: coroutine 4 end sleep
2026-03-13T20:01:06+00:00: coroutine 5 end sleep
2026-03-13T20:01:06+00:00: coroutine 6 end sleep
2026-03-13T20:01:06+00:00: coroutine 7 end sleep
2026-03-13T20:01:06+00:00: coroutine 8 end sleep
2026-03-13T20:01:06+00:00: coroutine 9 end sleep
从结果可以看出每个协程用了2秒,整体上的时间还是用了2秒,是不是很神奇!