一:前言
协程又称为微线程,纤程。英文名Coroutine:协程是一种用户态的轻量级线程
协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复之前保存的寄存器上下文和栈。因此:
协程能够保留上次一调用时的状态,能够进入上一次离开时所处的逻辑流的位置
协程的好处
无需线程上下文切换的开销
无需原子操作(不会被线程调度机制打断的操作)锁定以及同步的开销
方便切换控制流,简化编程模型
高并发+高扩展性+低成文:一个CPU支持上完的协程都不是问题,所以很适合高并发处理
协程的缺点
无法利用多核资源:协程的本质是单线程,需要和进程配合才能运行在多CPU上
进行阻塞(Blocking)操作(如IO时)会阻塞掉整个程序
协程的条件
必须在只有一个单线程里实现并发
修改共享数据不需加锁
用户程序里自己保存多个控制流的上下文栈
一个协程遇到IO操作自动切换到其它协程
使用yield实现协程
def consumer(name):
print("--->starting eating baozi...")
while True:
new_baozi = yield
print("[%s] is eating baozi %s" % (name, new_baozi))
def producer():
next(con)
next(con2)
n = 0
while n < 5:
n += 1
con.send(n)
con2.send(n)
print("\033[32;1m[producer]\033[0m is making baozi %s" % n)
if __name__ == '__main__':
con = consumer("c1")
con2 = consumer("c2")
p = producer()
二:Greenlet
greenlet是一个用C实现的协程模块,相比与python自带的yield,它可以使你在任意函数之间随意切换,而不需把这个函数先声明为generator
使用greenlet实现协程
from greenlet import greenlet
def f1():
print(12)
gr2.switch()
print(34)
gr2.switch()
def f2():
print(56)
gr1.switch()
print(78</