day4-生成器并行运算

概述

         之前只是介绍生成器,那有些同学就说了,这个生成器除了能节省资源,提高工作效率,但是我们再哪些场景下可以用呢?在哪些地方可以体现出它的价值呢?下面我们来逐一解答这些疑问。

生成器执行过程

程序执行过程

def consumer(name):
     print("%s准备发工资啦!"%name)
     while True:
          gongzi=yield
          print("工资%s来了,被%s领了!"%(gongzi,name))

x=consumer("huwei")
x.__next__()
#输出
huwei准备发工资啦!

我们再加几个__next__()方法:

def consumer(name): 
    print("%s准备发工资啦!"%name) 
    while True: 
          gongzi=yield 
          print("工资%s来了,被%s领了!"%(gongzi,name))

x=consumer("huwei")
x.__next__()
x.__next__()   
b="1个亿"
x.send(b)
x.__next__()
#输出
huwei准备发工资啦!
工资None来了,被huwei领了!
工资1个亿来了,被huwei领了!
工资None来了,被huwei领了!

# next()只是在调用(唤醒)yield,但是不会给其传值,而send除了能够调用(唤醒)同时还能给其传值

第一个例子没有执行print("工资%s来了,被%s领了!"%(gongzi,name)),接着我们来调试一下,看看具体过程:

...........................debug

yield实现串行下的并行效果

我们把"优化"发工资的再规范一下,可以使用

#-*-coding:utf-8-*-

import time
 
def consumer(name): #0
     print("%s准备发工资啦!"%name) #4
     while True:
           gongzi=yield #5
           print("工资%s来了,被%s领了!"%(gongzi,name)) #9
 
def producer(name):

     x=consumer("A")   #1 只是将consumer()变成一个生成器
     x1=consumer("B")  #2 只是将consumer()变成一个生成器
     x.__next__() #3
     x1.__next__() #6
     print("财务开始做工资啦!") #7
     for i in range(10):
          time.sleep(2)
          print("做了2个人的工资!")
          x.send(i) #8
          x1.send(i) #10

 
producer("dick")
#输出
A准备发工资啦!
B准备发工资啦!
财务开始做工资啦!
做了2个人的工资!
工资0来了,被A领了!
工资0来了,被B领了!
做了2个人的工资!
工资1来了,被A领了!
工资1来了,被B领了!
做了2个人的工资!
工资2来了,被A领了!
工资2来了,被B领了!

解析:在#1和#2只是将consumer()函数变成生成器(如果# 0 consumer是函数的话,我们执行consumer()就会直接打印),在这里#0是生成器,而我们第一次调用#3目的是要其打印#4,我们执行#3时,程序consumer才会继续往下执行,执行到#5处 自动中断返回,返回到#6,再从#6调用程序consumer会继续往下执行,执行到#5处 自动中断返回到#7继续向下执行,当执行到#8时将#8 I 的值赋值给yield,继续向下#9执行,执行后由于是while循环,又继续回到#5跳出返回到#10,接着#10又send I 赋值给#5,如此运行,直到结束

 

注意:实现单线程下的并行处理,虽然它仍然是串行依次处理,但是我们可以在不同的角色之间来回地切换,并且运行速度特别快,感觉上是并行的。注意,这个就是异步I/O的雏形。

posted @ 2017-07-26 10:13  Mr.hu  阅读(102)  评论(0编辑  收藏  举报