zoukankan      html  css  js  c++  java
  • 异步

    一.协程

    协程,又称微线程,纤程。英文名Coroutine。一句话说明什么是线程:协程是一种用户态的轻量级线程。

    线程是系统级别的,它们是由操作系统调度;协程是程序级别的,由程序员根据需要自己调度。我们把一个线程中的一个个函数叫做子程序,那么子程序在执行过程中可以中断去执行别的子程序;别的子程序也可以中断回来继续执行之前的子程序,这就是协程。也就是说同一线程下的一段代码<1>执行着执行着就可以中断,然后跳去执行另一段代码,当再次回来执行代码块<1>的时候,接着从之前中断的地方开始执行。

    协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈。因此:协程能保留上一次调用时的状态(即所有局部状态的一个特定组合),每次过程重入时,就相当于进入上一次调用的状态,换种说法:进入上一次离开时所处逻辑流的位置。

    1.yield实现:

    yield不但可以返回一个值,它还可以接收调用者发出的参数

    def consumer():
        print('开始消费了')
        ret = ''
        while True:
            producter = yield ret
            if not producter:
                return
            print('消费了%s' % producter)
            ret = '200 ok'
    
    def produce(consu):
        # 启动生成器,第一次必须用None  <==> consumer.__next__()
        consu.send(None)
        n = 0
        while n < 5:
            n += 1
            print('生产了苹果%d' % n)
            ret = consu.send('苹果%d' % n)
            print('消费者返回:%s' % ret)
        consu.close()
    
    c = consumer()
    produce(c)
    

      

    执行流程:
    首先调用consu.send(None)启动生成器;
    然后,一旦生产了东西,通过consu.send(n)切换到consumer执行;
    consumer通过yield拿到消息,处理,又通过yield把结果传回;
    produce拿到consumer处理的结果,继续生产下一条消息;
    produce决定不生产了,通过c.close()关闭consumer,整个过程结束。

    2.其余还有第三方包greenlet和gevent实现

    二.asyncio

    asyncio的编程模型就是一个消息循环

    import threading
    import asyncio
    
    @asyncio.coroutine
    def hello():
        print('Hello world! (%s)' % threading.currentThread())
        # 模拟耗时操作
        yield from asyncio.sleep(1)
        print('Hello again! (%s)' % threading.currentThread())
    
    # 获取EventLoop:
    loop = asyncio.get_event_loop()
    tasks = [hello(), hello()]
    # 执行coroutine
    loop.run_until_complete(asyncio.wait(tasks))
    loop.close()
    

      

    三.async/await

    import asyncio
    
    #async申明这是一个异步函数, await用于挂起自身,执行耗时操作
    async def get():
        await asyncio.sleep(1)
        return 100
    
    async def hello():
        print('开始了')
        # 模拟耗时操作
        a = await get()
        print('结束了%s' % a)
    
    loop = asyncio.get_event_loop()
    tasks = [hello(), hello()]
    loop.run_until_complete(asyncio.wait(tasks))
    loop.close()
    

      

    四.aiohttp

    aiohttp是基于asyncio实现的HTTP框架

    异步简单爬虫示例:

    import asyncio
    import aiohttp
    
    get_contents = []
    
    async def html(url):
        headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36'}
        async with aiohttp.ClientSession() as session:
            async with session.get(url, headers=headers, timeout=1, verify_ssl=False) as r:
                body = await r.text()
                get_contents.append(body)
    
    
    loop = asyncio.get_event_loop()
    tasks = [html('http://www.baidu.com'), html('http://www.163.com')]
    loop.run_until_complete(asyncio.wait(tasks))
    loop.close()
    
    print(len(get_contents))
    

      

    输出:
    2

  • 相关阅读:
    ifdef有大用处
    osgEarth编译
    CyanogenMod 7.1 for Sony Ericsson X8 下载 CM7.1 for 索爱X8下载
    ArcGIS影像配准与空间配准
    ArcGIS Server的切图原理深入
    Arcgis server的rest服务url写法解读
    地图切片公式
    新随笔
    solr的java调用
    配置文件
  • 原文地址:https://www.cnblogs.com/itfenqing/p/10275202.html
Copyright © 2011-2022 走看看