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'

以上問題不知道是否是由於版本問題?待解決...........

相關文章
相關標籤/搜索