zoukankan      html  css  js  c++  java
  • 用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互相切换,实现协程的功能

  • 相关阅读:
    模板 无源汇上下界可行流 loj115
    ICPC2018JiaozuoE Resistors in Parallel 高精度 数论
    hdu 2255 奔小康赚大钱 最佳匹配 KM算法
    ICPC2018Beijing 现场赛D Frog and Portal 构造
    codeforce 1175E Minimal Segment Cover ST表 倍增思想
    ICPC2018Jiaozuo 现场赛H Can You Solve the Harder Problem? 后缀数组 树上差分 ST表 口胡题解
    luogu P1966 火柴排队 树状数组 逆序对 离散化
    luogu P1970 花匠 贪心
    luogu P1967 货车运输 最大生成树 倍增LCA
    luogu P1315 观光公交 贪心
  • 原文地址:https://www.cnblogs.com/ALADL/p/9585049.html
Copyright © 2011-2022 走看看