iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >python协程
  • 763
分享到

python协程

python协程 2023-01-30 23:01:40 763人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

目录 python协程入门 函数的执行顺序 协程概念 总结 Python协程入门 函

目录

Python协程入门

函数的执行顺序

在了解协程之前, 我们需要再次回想一下python中的多个函数执行的顺序是怎样的?

  • 我们看看下面一段代码,在没有在解释器运行之前,你是否知道函数的最后输出的内容呢

    #!/usr/bin/python
    #-*-coding:utf-8-*-
    
    def A1():
        print("i am the func:{}".fORMat(A1.__name__))
    
    def B1():
        A1()
        print("i am the func:{}".format(B1.__name__))
    
    
    def C1():
        print("i am the func:{}".format(C1.__name__))
        B1()
        print("---all funcs over---")
    
    if __name__ == "__main__":
        C1()
    
    #output
    i am the func:C1
    i am the func:A1
    i am the func:B1
    ---all funcs over---
    

    函数从C1开始,在执行过程中,遇到函数B1此时函数就跳转到函数B1去执行,在跳转到B1后,在其函数内又遇到A1函数,此时cpu又会切换到A1函数所在的内存中执行,当A1执行完毕后,跳转到B1继续执行,B1执行完毕后,才返回到函数C1执行!

    内部执行流程图如下

对于正常函数之间的调用:是通过 栈执行的一个子程序,子程序调用总是一个入口,返回之后再继续跳转到另一个函数内部。

协程概念

  • 看上去也是子程序,但是在自沉协的内部可以中断, 然后转而执行别的子程序, 但不是转到别的函数,它的执行过程像线程的切换,但是只会在一个线程中执行(中断,跳转执行)

  • 优点(与线程相比):执行效率极高,因为只有一个线程, 不存在同时写同一个变量的冲突,在协程中共享资源不用加多线程在执行对同一个数据写操作时为了避免冲突必须加锁),只需要判断状态即可
  • 如何实现: 通过生成器实现,函数中通过关键字yield实现,控制函数内部的阶段性执行,返回值的时一个生成器。

一个简单的协程

  • 如何调用

    #!/usr/bin/python
    #-*-coding:utf-8-*-
    def A1():
        print(1)
        yield  10
        print(2)
        yield 20
    
    if __name__ == "__main__":
        m= A1()
        try:
            print(type(m))
            print(next(m))
            print(next(m))
            print(next(m))
        except StopIteration:
            print("over")
    #output
    <class 'generator'>
    1
    10
    2
    20
    over

    执行A1,输出的是<class ’generator’>,可以看出,函数使用yield关键字之后,类型变成了一个生成器, 调用的时候使用next来执行,

    • 第一次通过next执行遇到yield之后,会中断执行后面的代码
    • 第二次通过next执行时,cpu会读取上次执行的位置,再次执行直到遇到yield执行完毕后再次停止
    • 当检测到没有yield时,生成器再也没有更多的数据时,会发生StopIteration

    具有生成器的所有的特性。

协程间的数据传输

协程是单个函数(一个线程),可以随时中断执行,也就意味着,在中断过程中,可以做一些有意义的事情(它并不像普通函数间的调用,一个函数在执行后是没办法继续去操作该函数的,如传递新的数据,修改函数内部的变量等),比如可以在此时传递新的数据!

  • 由于协程是 函数生成器的综合体,so,它拥有了两者的共同特性

    • 可以携带参数
    • 可以有返回值
    • 可以使用for循环调用
    • 可以使用send方法
  • 看这个列子,注意理解协程函数是通过什么样的方式在执行过程中传递外部数据的

    #!/usr/bin/python
    #-*-coding:utf-8-*-
    
    def run():
        # 空变量,存储的作用, data始终为空
        data = ""
    
        r = yield data              # 返回数据,r用来接收从函数外面传递的数据
        print(1, r, data)
    
        r = yield data
        print(2, r, data)
    
        yield 20
    
    
    if __name__ == "__main__":
        m = run()
        # 启动协程
        m.send(None)
        m.send("a")
        m.send("b")
        print("*****")
    
    #output
    1 a 
    2 b 
    *****

    代码解释

    • 先看入口: m=run() 想象一下,如果run函数中yield是关键字 return, 那么此时函数返回的是一个变量,但是此时使用yield ,那么一切都变了, 它不再是一个函数,而是一个生成器。

    • m 是一个生成器, 所以它有生成器的特性,send是它的方法,使用m.send(None)来启动协程
    • m.send("a"), 此时将“a”的值传递进生成器内部,那么内部如何接受这个外来数据呢?于是我们用r变量来接收
    • send方法到底执行了哪些操作呢?实际上是包含来两个步骤
      • 发送数据到生成器内部
      • 执行next()方法直到遇到下一个yield暂停执行
    • data 始终为字符串,因为 r 其实与 data没有任何关系,在run函数未执行完毕之前,data的值没有发生任何改变
    • line 14, send执行是遇到下一个yield才会终止,所以必须使用yield终止

协程之生产者消费者模型

  • 什么是生产者与消费者模型?

    • 在现实生活中: 生产者随处可见,顾名思义可以创建某些产品的机构或个人,消费者则是用来消化某些产品的用户或者机构
    • 在计算机的世界:这是一种设计模型,我们都知道,不管是小到简单的一组数据的加减,还是WEB工程项目,本质都是cpu内部执行的一段代码,代码运行在计算机内部(内存中)都是读写操作,生产者消费者模型中,生产者用来产生程序内部需要的数据,消费者则用来处理这些数据!
  • 之前我们使用多线程与消息队列实现来消费者与生产者模型,那么协程是否也能实现此种设计模型呢?

    • 协程可以从外部传递数据的特性
    • 可以随时中断执行
  • 生产者消费者

    #!/usr/bin/python
    #-*-coding:utf-8-*-
    
    '''协程实现生产者与消费者模型'''
    
    
    def product(c):
        '''生产者:厨师生产包子
        - 生产者接收消费者发来的消息. 以 c.send(None)触发生成器函数
        '''
        c.send(None)
        for i in range(100000):
            if i == 0:
                print("没包子了,厨师正在赶做...")
            else:
                print("厨师包好了第{}个包子".format(i))
            c.send(i)
            print("顾客吃完了{}个包子".format(i))
        print("今天限量包子已卖完")
        c.close()
    
    
    def customer():
        '''消费者:顾客吃包子'''
        data = ""  # 定义一个常量用来为生成器占用内存
        while True:
            n = yield data  # n 用来接收c.send发送来的数据
            if not n:  # 判断n 是否接收到了数据,如果没有接收到,实际n = data
                print("已经没包子了,稍等...")
                continue
            print("顾客正在吃第{}个包子".format(n))
    
    if __name__ == "__main__":
        c = customer()
        product(c)
    

总结

  • 协程的实现: yield关键字
  • 协程实际上是 : 生成器函数
  • 使用g.send(None)触发协程
  • g.send("a") 像xie程内部发送数据
  • g.close()关闭协程

--结束END--

本文标题: python协程

本文链接: https://www.lsjlt.com/news/181271.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • python协程
    目录 python协程入门 函数的执行顺序 协程概念 总结 python协程入门 函...
    99+
    2023-01-30
    python 协程
  • python 协程
    进程和线程都会的切换都要消耗时间,保存线程进程当前状态以便下次继续执行。在不怎么需要cpu的程序中,即相对于IO密集型的程序,协程相对于线程进程资源消耗更小,切换更快,更适用于IO密集型。协程也是单线程的,没法利用cpu的多核,想利用cp...
    99+
    2023-01-30
    python 协程
  • python协程与golang协程的区
    进程、线程和协程 进程的定义: 进程,是计算机中已运行程序的实体。程序本身只是指令、数据及其组织形式的描述,进程才是程序的真正运行实例。 线程的定义: 操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。 进程...
    99+
    2023-01-31
    python golang
  • python线程、协程
    线程Threading用于提供线程相关的操作,线程是应用程序中工作的最小单元。更多方法:start            线程准备就绪,等待CPU调度setName      为线程设置名称getName      获取线程名称setDae...
    99+
    2023-01-31
    线程 python 协程
  • Python 协程与 JavaScript 协程的对比
    目录1、前言2、什么是协程?3、混乱的历史3.1Python协程的进化4、JavaScript协程的进化5、Python协程成熟体5.1协程(coroutine)5.2任务(Task...
    99+
    2024-04-02
  • python之协程
      协程,又称微线程,纤程。英文名Coroutine。协程是一种用户态的轻量级线程。  所谓用户态就是说协程是由用户来控制的,CPU不认识协程,协程是跑在线程中的。  协程拥有自己的寄存器上下文栈。协程调试切换时,将寄存器上下文栈保存到其他...
    99+
    2023-01-31
    python
  • Python进程/线程/协程
    第1章 操作系统历史1.1为什么要有操作系统?程序员无法把所有的硬件操作细节全部了解到,管理这些硬件并且加以优化使用时非常繁琐的工作,这个繁琐的工作就是由操作系统来干的,有了它,程序员就从这些繁琐的工作中解脱了出来,只需要考虑自己的应用软件...
    99+
    2023-01-31
    线程 进程 Python
  • Python下的协程
    线程和进程的操作是由程序触发系统接口,最后的执行者是系统;协程的操作则是程序员。协程存在的意义:对于多线程应用,CPU通过切片的方式来切换线程间的执行,线程切换时需要耗时(保存状态,下次继续)。协程,则只使用一个线程,在一个线程中规定某个代...
    99+
    2023-01-31
    Python
  • Python协程之Gevent
    协程,又称微线程,即为轻量级的线程。python中实现协程是基于Gevent模块,Gevent模块内部封装了greenlet模块;greenlet模块实现了在单线程中切换状态,Gevent模块在此之上还实现了遇到I/O操作自动切换,使程序运...
    99+
    2023-01-31
    Python Gevent
  • 浅谈Python协程asyncio
    一、协程 官方描述; 协程是子例程的更一般形式。 子例程可以在某一点进入并在另一点退出。 协程则可以在许多不同的点上进入、退出和恢复。 它们可通过 async def 语句来实现。...
    99+
    2024-04-02
  • python协程--asyncio模块(
    在高并发的场景下,python提供了一个多线程的模块threading,但似乎这个模块并不近人如意,原因在于cpython本身的全局解析锁(GIL)问题,在一段时间片内实际上的执行是单线程的。同时还存在着资源争夺的问题。python3.4...
    99+
    2023-01-30
    模块 python 协程
  • python并发之协程
    概念 协程,又称微线程。英文名Coroutine。 子程序,或者称为函数,在所有语言中都是层级调用,比如A调用B,B在执行过程中又调用了C,C执行完毕返回,B执行完毕返回,最后是A执行完毕。所以子程序调用是通过栈实现的,一个线程...
    99+
    2023-01-31
    python
  • Python并发编程之协程
    协程介绍 协程:是单线程下的并发,又称微线程,纤程。协程是一种用户态的轻量级线程,即线程是由用户程序自己控制调度的。 需要强调的是: #1. python的线程属于内核级别的,即由操作系统控制调度(如单线程遇到io或执行时间过长就会被迫...
    99+
    2023-01-30
    Python
  • Python网络编程之协程
    What is the association与子例程一样,协程也是一种程序组件。 相对子例程而言,协程更为一般和灵活,但在实践中使用没有子例程那样广泛。 协程源自Simula和Modula-2语言,但也有其他语言支持。 协程更适合于用来实...
    99+
    2023-01-31
    网络编程 Python
  • Python进程/线程/协程相关
    1、获取进程ID。(getpid)os.getpid()2、获取父进程ID。(getppid)os.getppid()3、获取线程ID。(get_ident)(1)、进程内局部标识。import threading threading.ge...
    99+
    2023-01-31
    线程 进程 Python
  • Python:线程、进程与协程(7)——
         前面转载了一篇分析进程池源码的博文,是一篇分析进程池很全面的文章,点击此处可以阅读。在Python中还有一个线程池的概念,它也有并发处理能力,在一定程度上能提高系统运行效率;不正之处欢迎批评指正。     线程的生命周期可以分为5...
    99+
    2023-01-31
    线程 进程 Python
  • Python:线程、进程与协程(3)——
        Queue模块是提供队列操作的模块,队列是线程间最常用的交换数据的形式。该模块提供了三种队列:Queue.Queue(maxsize):先进先出,maxsize是队列的大小,其值为非正数时为无线循环队列Queue.LifoQueue...
    99+
    2023-01-31
    线程 进程 Python
  • Python:线程、进程与协程(2)—
        上一篇博文介绍了Python中线程、进程与协程的基本概念,通过这几天的学习总结,下面来讲讲Python的threading模块。首先来看看threading模块有哪些方法和类吧。主要有:Thread :线程类,这是用的最多的一个类,...
    99+
    2023-01-31
    线程 进程 Python
  • Python:线程、进程与协程(1)——
            最近的业余时间主要放在了学习Python线程、进程和协程里,第一次用python的多线程和多进程是在两个月前,当时只是简单的看了几篇博文然后就跟着用,没有仔细去研究,第一次用的感觉它们其实挺简单的,最近这段时间通过看书, 看...
    99+
    2023-01-31
    线程 进程 Python
  • Python:线程、进程与协程(6)——
        上篇博文介绍了multiprocessing模块的内存共享(点击此处可以参看),下面讲进程池。有些情况下,所要完成的工作可以上篇博文介绍了multiprocessing模块的内存共享,下面讲进程池。有些情况下,所要完成的工作可以分解...
    99+
    2023-01-31
    线程 进程 Python
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作