什么是协程:
协程又称为微线程,是Python另外一种实现多任务的方式,
只是比线程更小占用更小的执行单元(理解为需要的资源),
为啥是一个执行单元,因为自带CPU上下文;
通俗的理解:
在一个线程中的某个函数,可以在任何地方保存当前函数的一些临时变量信息,然后切换到另外一个函数中运行,注意不是通过调用函数的方式实现,并且切换的次数和何时切换到原本函数都是开发者自己决定;
协程和线程的差异:
在实现多任务时,线程切换从系统层面远不只是保存和恢复CPU上下文那么简单,操作系统为了程序运行高效,每个线程都有自己的缓存cache等数据,操作系统还会帮你做这些数据的恢复操作,所以线程的切换比较耗性能,但是协程的切换只是单纯的操作CPU上下文,所以一秒钟切换上百万次系统都扛得住;
生成器实现协程
讲协程之前我们先回顾一下生成器,因为携程的底层实现就是生成器:
生成器:
- 使用元组推导式实现;
- 使用yeild实现;
先看一个简单的协程:
#使用元组推导式实现
g1 = (i for i in range(10))
#yeild实现推导式
def gen():
for i in range(10):
yield i
g2 = gen()
print(g1)
print(g2)
运行结果:
<generator object <genexpr> at 0x000001F0AB426AC8>
<generator object gen at 0x000001F0AB426B48>
使用生成器实现协程:
def work1():
for i in range(4):
print('work1---{}'.format(i))
yield i
def work2():
for i in range(3):
print('work2---{}'.format(i))
yield i
def work3():
for i in range(4):
print('work3---{}'.format(i))
yield i
g1 = work1()
g2 = work2()
g3 = work3()
while True:
next(g1)
next(g2)
next(g3)
运行结果:
File "E:/workspace/python/pythonDemo/0917/yeild01.py", line 23, in <module>
next(g2)
StopIteration
work1---0
work2---0
work3---0
work1---1
work2---1
work3---1
work1---2
work2---2
work3---2
work1---3
报错,因为元素为空时再next取值就会报错,我们捕获一下异常:
def work1():
for i in range(4):
print('work1---{}'.format(i))
yield i
def work2():
for i in range(3):
print('work2---{}'.format(i))
yield i
def work3():
for i in range(4):
print('work3---{}'.format(i))
yield i
g1 = work1()
g2 = work2()
g3 = work3()
while True:
try:
next(g1)
next(g2)
next(g3)
except StopIteration:
pass
运行结果:
work1---0
work2---0
work3---0
work1---1
work2---1
work3---1
work1---2
work2---2
work3---2
work1---3