zoukankan      html  css  js  c++  java
  • 【python】异步IO

    No1:

    协程看上去也是子程序,但执行过程中,在子程序内部可中断,然后转而执行别的子程序,在适当的时候再返回来接着执行。

    优势:

    1.最大的优势就是协程极高的执行效率。因为子程序切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销,和多线程比,线程数量越多,协程的性能优势就越明显。

    2.不需要多线程的锁机制,因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁,只需要判断状态就好了,所以执行效率比多线程高很多。

    No2:

    因为协程是一个线程执行,那怎么利用多核CPU呢?最简单的方法是多进程+协程,既充分利用多核,又充分发挥协程的高效率,可获得极高的性能。

    Python对协程的支持是通过generator实现的。

    def consumer():
        r = ''
        while True:
            n = yield r
            if not n:
                return
            print('[CONSUMER] Consuming %s...' % n)
            r = '200 OK'
    
    def produce(c):
        c.send(None)
        n = 0
        while n < 5:
            n = n + 1
            print('[PRODUCER] Producing %s...' % n)
            r = c.send(n)
            print('[PRODUCER] Consumer return: %s' % r)
        c.close()
    
    c = consumer()
    produce(c)

    运行结果

    consumer函数是一个generator,把一个consumer传入produce后:

    1. 首先调用c.send(None)启动生成器;

    2. 然后,一旦生产了东西,通过c.send(n)切换到consumer执行;

    3. consumer通过yield拿到消息,处理,又通过yield把结果传回;

    4. produce拿到consumer处理的结果,继续生产下一条消息;

    5. produce决定不生产了,通过c.close()关闭consumer,整个过程结束。

    整个流程无锁,由一个线程执行,produceconsumer协作完成任务,所以称为“协程”,而非线程的抢占式多任务

    No3:

    【asyncio】

    import asyncio
    
    async def hello():
        print("Hello world!")
        r=await asyncio.sleep(1)
        print("Hello again!")
        
    loop=asyncio.get_event_loop()
    loop.run_until_complete(hello())
    loop.close()

    运行结果

    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())
        
    loop=asyncio.get_event_loop()
    tasks=[hello(),hello()]
    loop.run_until_complete(asyncio.wait(tasks))
    loop.close()

    运行结果

    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()))
        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()

    运行结果

    No4:

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

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

    No5:

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

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

    No6:

    【aiohttp】

    import asyncio
    
    from aiohttp import web
    
    async def index(request):
        await asyncio.sleep(0.5)
        return web.Response(body=b'<h1>Index</h1>', content_type='text/html')
    
    async def hello(request):
        await asyncio.sleep(0.5)
        text='<h1>hello,%s!</h1>' % request.match_info['name']
        return web.Response(body=text.encode('utf-8'), content_type='text/html')
        
    async def init(loop):
        app=web.Application(loop=loop)
        app.router.add_route('GET','/',index)
        app.router.add_route('GET','/hello/{name}',hello)
        srv=await loop.create_server(app.make_handler(),'127.0.0.1',8000)
        print('Server started at http://127.0.0.1:8000...')
        return srv
        
    loop=asyncio.get_event_loop()
    loop.run_until_complete(init(loop))
    loop.run_forever()

    运行结果

  • 相关阅读:
    DVS6446教程链接
    今晚做的二值化和分割
    Sybase ETL
    QR码的结构
    cannot open file Default/configPkg/linker.cmd 错误
    QR 码的位置检测符
    QR Code
    C6000 OMAP DAVINCI的关系
    Davinci笔记 DSP子系统 VS ARM子系统
    ETL简介
  • 原文地址:https://www.cnblogs.com/anni-qianqian/p/9278286.html
Copyright © 2011-2022 走看看