異步IO
阿新 • • 發佈:2017-08-12
優勢 操作 使用 數據 http coroutine nbsp for ask
IO操作:讀寫文件、發送網絡數據
在一個線程中,CPU執行代碼的速度極快,然而,一旦遇到IO操作,就需要等待IO操作完成。這是同步IO。
由於我們要解決的問題是CPU高速執行能力和IO設備的龜速嚴重不匹配,多線程和多進程只是解決這一問題的一種方法。
另一種解決IO問題的方法是異步IO。
loop = get_event_loop() while True: event = loop.get_event() process_event(event)
異步IO模型在一個消息循環中,主線程不斷地重復“讀取消息-處理消息”
Coroutine 即協程,它的優勢是只有一個線程
asyncio模塊能實現異步IO:
import asyncio @asyncio.coroutine def hello(): print("Hello world!") # 異步調用asyncio.sleep(1): 模擬一個耗時1秒的IO操作,在此期間,主線程並未等待 r = yield from asyncio.sleep(1) print("Hello again!") # 獲取EventLoop: loop = asyncio.get_event_loop() # 執行coroutine loop.run_until_complete(hello()) loop.close()
其實多個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\r\nHost: %s\r\n\r\n‘ % host 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‘ % (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()
async和await是針對coroutine的新語法,要使用新的語法,只需要做兩步簡單的替換:
[email protected];
2.把yield from替換為await。
async def hello(): print("Hello world!") r = await asyncio.sleep(1) print("Hello again!")
單線程+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()
https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/00143208573480558080fa77514407cb23834c78c6c7309000 筆記
異步IO