zoukankan      html  css  js  c++  java
  • async /await相关知识理解

    asyncio提供的@asyncio.coroutine可以把一个generator标记为coroutine类型,然后在coroutine内部用yield from调用另一个coroutine实现异步操作。

    为了简化并更好地标识异步IO,从Python 3.5开始引入了新的语法asyncawait,可以让coroutine的代码更简洁易读。

    请注意,asyncawait是针对coroutine的新语法,要使用新的语法,只需要做两步简单的替换:

      

    1. @asyncio.coroutine替换为async
    2. yield from替换为await


    实例1:

    @asyncio.coroutine把一个generator标记为coroutine类型,然后,我们就把这个coroutine扔到EventLoop中执行。

    hello()会首先打印出Hello world!,然后,yield from语法可以让我们方便地调用另一个generator。由于asyncio.sleep()也是一个coroutine,所以线程不会等待asyncio.sleep(),而是直接中断并执行下一个消息循环。当asyncio.sleep()返回时,线程就可以从yield from拿到返回值(此处是None),然后接着执行下一行语句。

    asyncio.sleep(1)看成是一个耗时1秒的IO操作,在此期间,主线程并未等待,而是去执行EventLoop中其他可以执行的coroutine了,因此可以实现并发执行。

    我们用Task封装两个coroutine试试:

    asyncio的异步网络连接来获取sina、sohu和163的网站首页:

    import asyncio
    
    @asyncio.coroutine
    def wget(host):
        print('wget %s...' % host)
        connect = asyncio.open_connection(host, 80)
        reader, writer = yield from connect
        header = 'GET / HTTP/1.0
    Host: %s
    
    ' % host
        writer.write(header.encode('utf-8'))
        yield from writer.drain()
        while True:
            line = yield from reader.readline()
            if line == b'
    ':
                break
            print('%s header > %s' % (host, line.decode('utf-8').rstrip()))
        # Ignore the body, close the socket
        writer.close()
    
    loop = asyncio.get_event_loop()
    tasks = [wget(host) for host in ['www.sina.com.cn', 'www.sohu.com', 'www.163.com']]
    loop.run_until_complete(asyncio.wait(tasks))
    loop.close()

    result:

    wget www.sohu.com...
    wget www.sina.com.cn...
    wget www.163.com...
    (等待一段时间)
    (打印出sohu的header)
    www.sohu.com header > HTTP/1.1 200 OK
    www.sohu.com header > Content-Type: text/html
    ...
    (打印出sina的header)
    www.sina.com.cn header > HTTP/1.1 200 OK
    www.sina.com.cn header > Date: Wed, 20 May 2015 04:56:33 GMT
    ...
    (打印出163的header)
    www.163.com header > HTTP/1.0 302 Moved Temporarily
    www.163.com header > Server: Cdn Cache Server V2.0
    ...

    可见3个连接由一个线程通过coroutine并发完成。

    小结

    asyncio提供了完善的异步IO支持;

    异步操作需要在coroutine中通过yield from完成;

    多个coroutine可以封装成一组Task然后并发执行。

    实例2:async

    import asyncio
    import time
    
    start = time.time()
    
    
    def tic():
        return 'at %1.1f seconds' % (time.time() - start)
    
    
    async def gr1():
        # Busy waits for a second, but we don't want to stick around...
        print('gr1 started work: {}'.format(tic()))
        # 暂停两秒,但不阻塞时间循环,下同
        await asyncio.sleep(2)
        print('gr1 ended work: {}'.format(tic()))
    
    
    async def gr2():
        # Busy waits for a second, but we don't want to stick around...
        print('gr2 started work: {}'.format(tic()))
        await asyncio.sleep(2)
        print('gr2 Ended work: {}'.format(tic()))
    
    
    async def gr3():
        print("Let's do some stuff while the coroutines are blocked, {}".format(tic()))
        await asyncio.sleep(1)
        print("Done!")
    
    # 事件循环
    ioloop = asyncio.get_event_loop()
    
    # tasks中也可以使用asyncio.ensure_future(gr1())..
    tasks = [
        ioloop.create_task(gr1()),
        ioloop.create_task(gr2()),
        ioloop.create_task(gr3())
    ]
    ioloop.run_until_complete(asyncio.wait(tasks))
    ioloop.close()
    
    
    output:
        gr1 started work: at 0.0 seconds
        gr2 started work: at 0.0 seconds
        Let's do some stuff while the coroutines are blocked, at 0.0 seconds
        Done!
        gr2 Ended work: at 2.0 seconds
        gr1 ended work: at 2.0 seconds
    
    
  • 相关阅读:
    AE开发中Geometry到Polyline/Polygon的转换--转载
    asp.net MVC Views-----Controller传递数据方法
    百度翻译APi接口实现
    javascript添加删除行信息
    XMLDocument
    GDI绘制图像
    测试局域网内网络数据
    HL7 V2 分隔符
    IHE-PIX 备注
    数据库关键字 (Oracle, SQL Server, DB2)
  • 原文地址:https://www.cnblogs.com/cjj-zyj/p/10233225.html
Copyright © 2011-2022 走看看