使用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阻塞的时间可以和执行任务代码共享这段时间,那么才真正的提高了程序的执行效率