1. 程式人生 > >異步IO

異步IO

優勢 操作 使用 數據 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