使用yield和send实现简单的协程函数

使用yield和send实现协程

协程的本质是在一个线程里实现多个任务之间的来回切换,我们使用yield和send可以实现简单的协程

 1 def pro():
 2     print(1)
 3     n = yield "a"
 4     print(n)
 5     yield "b"
 6 
 7 
 8 def con():
 9     g = pro()
10     a = next(g)
11     print(a)
12     b = g.send(2)
13     print(b)
14     
15 
16 con()

首先我们来分析一下,我们定义了两个函数:pro是生产者,con是消费者,利用yield和send可以在两个函数之间切换,send是将值传给上一个yield,然后执行pro函数的代码直到下一个yield时,又会

返回到con函数,这样就实现了两个任务之间的来回切换,具体分析间如下代码:

 1 # def pro():    # ----第3步
 2 #     print(1)      # 打印1-----第5步
 3 #     n = yield "a"   # 执行等号右边的语句,把"a"的值传给next(g)这个整体(之后跳转到con函数)----第6步    # 把2的值赋给变量n---第10步
 4 #     print(n)    # 打印n---第11步
 5 #     yield "b"   # 执行yield "b"语句---第12步
 6 #
 7 #
 8 # def con():
 9 #     g = pro()    # 获取生成器-----第2步
10 #     a = next(g)    # 执行等号右边的语句(之后会跳转到pro函数)---第4步   # 把"a"是值赋给变量a-----第7步
11 #     print(a)      # 打印a----第8步
12 #     b = g.send(2)  # 执行等号右边的语句,把2发送给上一个yield----第9步   # 把"b"的值赋给变量b----第13步
13 #     print(b)      # 打印b----第14步
14 #
15 #
16 # con()    # 执行con函数-----第1步

注意:

(1)yield、next和send左边有等号时(第3、10、12行)等号两边的语句是分开执行的,并不是yield一个值后马上把值赋给左边的变量,而是执行生成器函数,直到遇到下一个yield,再将yield的值传给这个变量

(2)yield切换也会花时间的,所以如果任务没有I/O。那么在两个任务之间切换反而会降低效率,因为每一次切换都要记录状态,在切换回来之后还要读取状态

(3)yield只能做到状态保存和状态切换,不能遇到I/O自动切换

(4)只有遇到I/O时能够自动切换,并且I/O阻塞的时间可以和执行任务代码共享这段时间,那么才真正的提高了程序的执行效率

 

posted @ 2019-02-18 09:52  乘月归  阅读(224)  评论(0编辑  收藏  举报