谈谈python协程

谈谈python协程

什么是协程

wiki解释如下:

Coroutines are computer program components that generalize subroutines for non-preemptive multitasking, by allowing multiple entry points for suspending and resuming execution at certain locations.

简单的解释就是一个可以多次暂停执行,并且可以恢复继续执行的函数。

从yield到异步编程

网上很多文章都说python 的协程可以使用编写同步代码的方式编写异步程序。

有一个问题一直困扰着我,只用yield就可以实现异步编程吗?

自己也尝试去这样做,发现事情似乎没有这么简单。

假设一种场景,服务器上多个任务需要读取数据库,但是读取数据库比较费时,如果仅使用yield实现的协程,是否可以实现异步IO,提高运行效率?

  import time
  from collections import deque


  def readdb():
      time.sleep(3)
      return 3


  def acceptReq():
      print "accept request"

  def getData(num)data= -1
      while True:
          print "get data{} start".format(str(num))
          yield data
          data = readdb()
          print "get data{} end".format(str(num))

  tasks = deque()
  tasks.extend([getData(1), acceptReq(), getData(3)])

  def run():
      #acceptReq()

      #ret = 0
      while tasks:
          task = tasks.popleft()
          try :
              ret = next(task)
              #print ret
              tasks.append(task)
              #acceptReq()
          except StopIteration:
              print("end")

  if __name__=='__main__':
      run()

其实分析代码可以看出,效率并没有得到提升,我们希望的是当一个getdata的task在进行IO操作时,另一个acceptReq的task可以接受请求,当数据读取完成,就可以切换回getdata继续后续的操作,由于没有一个通知机制,所以并不能告诉调用函数IO操作已完成,所以还是会造成占用CPU等待的情况。

python的yield的关键字就可以实现函数的暂停和恢复执行。但是要实现异步编程光能够暂停和恢复函数的执行是不够的,还需要一个时间循环的特性,python3.4加入了asynico,asyncio + 生成器已经达到了异步编程的条件,在 Python3.4 中,我们就可以这样实现一个异步的模型。

协程的进化流程

                        asynico
yield ---------> 协程 ----------> 异步IO

猜你喜欢

转载自blog.csdn.net/yrx0619/article/details/81038798
今日推荐