zoukankan      html  css  js  c++  java
  • 协程

    协程定义

    协程的概念早期是由生成器yield -->yield from-->coroutine 演变而来的,熟悉yield关键字都知道一个重要的性质:会从程序上次中断的地方继续往下执行-->有自己的上下文寄存器和栈,不被内核控制,由开发者决定什么时候让出执行权。 现在有很多概念说是一种轻量级的线程(可能大概是因为协程在线程程中被创建)...
    个人理解:协程是一种用户态线程,切换不由内核而由用户自定义的线程.


    为什么有协程

    比较一下协程相对线程的优势|

    种类 线程 协程
    上下文切换开销
    并发能力
    资源同步考虑 考虑 不考虑

    协程概念组成

      1. 事件循环:所有的协程对象会被注册到该循环中
    
                      loop = asyncio.get_event_loop()
    
      2. 协程对象:常见IO操作封装在协程对象中,由关键字async 定义
    
                      async def request():
    
                             url = 'http://127.0.0.1:5000'
                             print('Waiting for', url)
                             result = await get(url)
                             print('Get response from', url, 'Result:', result)
    
      3.任务(期物):对协程对象的进一步封装,比如会赋予协程状态
    
                      task = asyncio.ensure_future(request())
    
      4.await关键字 (区别于asyncio.wait(fps,timeout=)):前者是关键字。后者解决事件循环中某一协程阻塞时间过程的问题
    

    协程的简单使用例子

    from flask import Flask
    import time
    
    app = Flask(__name__)
    
    
    @app.route('/')
    def index():
    
        time.sleep(3)
        return 'hello'
    
    
    if __name__ == '__main__':
    
        app.run(host='127.0.0.1', port=5000, threaded=True)
    

    使用流程 创建task(s),创建事件循环,将任务提交到事件循环中去:

        # tasks = [asyncio.ensure_future(get_files(i)) for i in range(6)]
        #创建任务列表(里面包含协程对象)  但是这并不是一个协程对象
        tasks = [asyncio.ensure_future(request()) for _ in range(4)]       
        #开启事件循环
        loop = asyncio.get_event_loop()
        #将任务列表添加到事件里面(若是协程对象 直接传协程对象)
        loop.run_until_complete(asyncio.wait(tasks))
        # p = ThreadPoolExecutor(max_workers=120)
        # for _ in range(100):
        #     p.submit(tes)
        # p.shutdown(wait=True)
        end = time.time()
        print('Cost time:', end - start)
    

    ![]

    这样的一个程序确实 是起到了协程的作用,遇到await关键字,将程序挂起,执行权让给其他协程,问题是在于请求网络阻塞的时间太长,而使得我们希望的高并发能力表现不出来,最终导致的是
    13s的时间,在理论上如果我们能够将请求网络这个操作挂起的话,就真正的能够实现我们所希望的并发能力,但是实际是 请求网络返回的Response类并没有实现__await__方法,所以只能生生阻塞成线性时间


    而这个时候 解决问题的库 aiohttp 就出来了,异步库:解决问题的核心是什么呢? ---->背后往往都会借助于IO的事件循环B来实现异步,我们请求网络遭遇阻塞时,将该套接字放入另外一个事件循环B里面,一直维持连接监听,而在主线程的事件循环A中 继续执行其他协程,当另外一个IO事件循环B里面的监听状态发生改变,会唤醒当前的事件循环A中的协程,进行我们需要的处理,这样!我们所期望的并发能力就出现了

    我也有用concurrent.future 里面的线程池 实现过100个线程异步提交和100个协程的比较 结果 前者是3.5S后者还是2.1左右 是真的猛啊!

    协程进一步了解

    0.协程的前世 yield 和 yield from是怎么实现原生协程的
    1.如何动态得往事件中添加任务
    2.如何查看事件循环中的各任务状态
    3.如何开启一个新的事件循环
    4.协程相关的异步库
    5.tornado里面的异步是怎么实现的...

    有错请指出哈........................

  • 相关阅读:
    WampServer Mysql配置
    Java实现 蓝桥杯VIP 算法提高 陶陶摘苹果2
    Java实现 蓝桥杯VIP 算法提高 陶陶摘苹果2
    Java实现 蓝桥杯VIP 算法提高 陶陶摘苹果2
    Java实现 蓝桥杯VIP 算法提高 质因数2
    Java实现 蓝桥杯VIP 算法提高 质因数2
    Java实现 蓝桥杯VIP 算法提高 质因数2
    Java实现 蓝桥杯VIP 算法提高 质因数2
    Java实现 蓝桥杯VIP 算法提高 质因数2
    Java实现 蓝桥杯VIP 算法提高 前10名
  • 原文地址:https://www.cnblogs.com/zengmu/p/13090226.html
Copyright © 2011-2022 走看看