简介
- 什么是协程?
- 协程又称为微线程,是比线程小的运行单位,自带CPU上下文
- CPU上下文
def func1(): while True: print(“func1 running…”) time.sleep(1) yield
def func2(): while True: print(“func2 running…”) time.sleep(1) yield
if name == ‘main‘: g1 = func1() g2 = func2()
while True:next(g1)next(g2)
**代码解析:**<br /><br />**运行结果:**<br />- 再函数的循环中使用yield可以创建生成器,步骤1并不会调用该函数只是创建生成器- 当第一次启动生成器时便调用了func1和func2,执行到yield语句时,函数返回值,挂起- 等待主程序第二次循环的时候,再次调用func1和func2,从yield语句开始执行<a name="pwsA0"></a>#### yield from双向通道```pythondef func():num = 0while True:num += 1print(num)w = yield numprint(w)if w == "":breakg = func()next(g)g.send("hi")g.send("hello")g.send("")
运行结果:
- send方法可以与函数进行传值,同时再次使用生成器
- 第一次使用生成器需要使用next方法,否则会报错,因为第一次使用的时候,程序执行到yield就会被挂起,由于等于号,程序是由左至右运行的,所以没有变量来接受send过去的值
- 相当于生产者已经生产了数据,然乎通过send将数据传递给消费者func函数
def func():num = 0while True:num += 1print(num)w = yield numprint(w)if w == "":breakdef generator():yield from func()g = func()next(g)g.send("hi")g.send("hello")g.send(None)

- yield from主要作用是打开双向通道,可以铺获异常

greenlet实现协程
- 需要手动切换任务 ```python from greenlet import greenlet
def func1(): for _ in range(3): print(“func1 over”)
# 任务切换到g2g2.switch()
def func2(): for _ in range(3): print(“func2 over”)
# 任务切换到g1g1.switch()
if name == ‘main‘:
# 创建协程g1 = greenlet(func1)g2 = greenlet(func2)# 切换到g1g1.switch()print("all over")
<a name="OaUDX"></a>#### gevent实现协程- 再遇到IO操作时不需要手动切换任务```pythonimport geventdef func1(n):for _ in range(n):print(gevent.getcurrent())gevent.sleep(1)def func2(n):for _ in range(n):# 查看当前协程print(gevent.getcurrent())# IO延时gevent.sleep(1)if __name__ == '__main__':g1 = gevent.spawn(func1, 5)g2 = gevent.spawn(func2, 4)g1.join()g2.join()

