python之异步IO

协程的用武之地

  • 并发量较大的系统和容易在IO方面出现瓶颈(磁盘IO,网络IO),采用多线程、多进程能够解决这个问题,固然线程、进程的切换时很消耗资源的。最好的解决方案是使用单线程方式解决并发IO问题--这就是协程发挥做用之处。html

  • 协程其实就是单线程在调度,是没法利用多核CPU,因此对于计算密集型的任务仍是须要考虑多进程+协程的方式。web

参考:编程

  http://blog.csdn.net/qq910894904/article/details/41699541网络

  http://www.cnblogs.com/xone/p/6198500.html多线程

 

异步IO库之asyncio

  • asyncio是Python 3.4版本引入的标准库,直接内置了对异步IO的支持。并发

  • asyncio的编程模型就是一个消息循环。咱们从asyncio模块中直接获取一个EventLoop的引用,而后把须要执行的协程扔到EventLoop中执行,就实现了异步IO。app

import asyncio
import threading

@asyncio.coroutine
def hello(index):
    print('hello world! index=%s,thread=%s' % (index,threading.currentThread()))
    yield from asyncio.sleep(1)
    print('hello  again! index=%s,thread=%s' % (index,threading.currentThread()))


loop=asyncio.get_event_loop()
tasks=[hello(i) for i in range(10000)]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
import asyncio

@asyncio.coroutine
def wget(url):
    print('wget %s...' % (url))
    connection = asyncio.open_connection(url,80)
    reader,writer=yield from connection
    header = 'GET / HTTP/1.0\r\nHOST: %s\r\n\r\n' % url
    writer.write(header.encode('utf-8'))
    yield from writer.drain()
    while True:
        line = yield from reader.readline()
        if line == b'\r\n':
            break
        print('%s header > %s' % (url,line.decode('utf-8').rstrip()))

    writer.close()


loop = asyncio.get_event_loop()
tasks=[wget(url) for url in ['www.sina.com.cn', 'www.sohu.com', 'www.163.com']]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()

 

async和await

  • 为了简化并更好地标识异步IO,从Python 3.5开始引入了新的语法async和await,能够让coroutine的代码更简洁易读。(其实Net中也有这个东东)

参考:框架

  https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/00144661533005329786387b5684be385062a121e834ac7000异步

 

aiohttp

  • aiohttp则是基于asyncio实现的HTTP框架
  • 于HTTP链接就是IO操做,所以能够用单线程+coroutine实现多用户的高并发支持
import asyncio

from aiohttp import web

async def index(request):
    await asyncio.sleep(0.5)
    return web.Response(body=b'<h1>Index</h1>')

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

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

 

报异常了:async

from aiohttp import web
ImportError: cannot import name 'web'

以上问题不知道是否是由于版本问题?待解决...........

相关文章
相关标签/搜索