• 用yield实现python协程


    刚刚介绍了pythonyield关键字,趁热打铁,现在来了解一下yield实现协程。

    引用官方的说法:

      

    与线程相比,协程更轻量。一个python线程大概占用8M内存,而一个协程只占用1KB不到内存。协程更适用于IO密集型的应用。

    当然在讲协程的实现之前,有必要先来看一下send方法。

    send方法

    yield表达式有一个返回值,send方法的作用就是控制这个返回值,send的参数就是yield表达式的返回值。我们来看一下官方文档上关于send的定义:

    举个栗子:

     上面的代码输出:

     

    第一次调用next的时候,程序从函数最开始处运行,打印出

    before yield

    执行到yield处,停在该处。

    接下来,向生成器send(1) 。send在这里起到两个作用,一个是将参数赋给yield的返回值,然后该返回值赋给了变量x;一个是继续程序的执行,直到下一次遇到yield停下来,第二个功能和next相似。其实,next就相当于send(None)。

    之心了send(1)后,x被赋值给yield的返回值,即send的参数1,并继续往下执行,打印出了

    after yield:1

    继续执行,回到循环的开始,向下执行,打印出

    before yield

    再次遇到yield,停在该处,等待下一次send 或者next的调用。

    向生成器send(2)。这里的步骤和send(1)相同,打印出下面两条后,在yield处停住。

    after yield:2

    before yield

    执行next(g),x被赋值为yield表达式的返回值,也就是None,继续向下执行,打印出

    after yield:None

    再次回到循环的开始,向下执行,打印出

    before yield

    程序运行结束

    现在是不是有点理解send了?

    yield和send实现python协程

    我们用协程实现一个生产者、消费者的例子:

    运行上面的程序,会输出:

    produce函数负责生产数据,consume函数负责消费数据。具体执行过程如下:

    1  首先调用consume函数。consume函数的返回是一个生成器,把这个生成器传入produce函数。

    2  produce函数中调用next(c)启动生成器。

    3  计算n = n + 1生成数据,一旦生产了数据,调用c.send(n) 切换到consume执行。

    4  consume函数中拿到数据后赋值给n,继续执行yield后面的语句

    5  consume函数中打印消费的数据,并设置返回值r,又回到循环的开始,通过yield把结果传回。

    6  produce拿到consume返回的值,继续生产下一个数据。

    7  5个数据生产完毕后,循环结束,通过c.close() 关闭consume,结束全过程

    produce和consume函数在一个线程内执行,通过调用send方法和yield互相切换,实现协程的功能

  • 相关阅读:
    junit单元测试踩过的坑
    Arrays.asList()需要注意的点
    oracle数据库学习笔记
    实训笔记
    spring事务学习笔记
    java锁
    jvm内存模型
    iOS 应用架构 (三)
    iOS 应用架构 (二)
    iOS 应用架构 (一)
  • 原文地址:https://www.cnblogs.com/ALADL/p/9585049.html
Copyright © 2020-2023  润新知