简介
- 什么是协程?
- 协程又称为微线程,是比线程小的运行单位,自带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双向通道
```python
def func():
num = 0
while True:
num += 1
print(num)
w = yield num
print(w)
if w == "":
break
g = func()
next(g)
g.send("hi")
g.send("hello")
g.send("")
运行结果:
- send方法可以与函数进行传值,同时再次使用生成器
- 第一次使用生成器需要使用next方法,否则会报错,因为第一次使用的时候,程序执行到yield就会被挂起,由于等于号,程序是由左至右运行的,所以没有变量来接受send过去的值
- 相当于生产者已经生产了数据,然乎通过send将数据传递给消费者func函数
def func():
num = 0
while True:
num += 1
print(num)
w = yield num
print(w)
if w == "":
break
def 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”)
# 任务切换到g2
g2.switch()
def func2(): for _ in range(3): print(“func2 over”)
# 任务切换到g1
g1.switch()
if name == ‘main‘:
# 创建协程
g1 = greenlet(func1)
g2 = greenlet(func2)
# 切换到g1
g1.switch()
print("all over")

<a name="OaUDX"></a>
#### gevent实现协程
- 再遇到IO操作时不需要手动切换任务
```python
import gevent
def 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()