异步IO

Posted liuw_flexi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了异步IO相关的知识,希望对你有一定的参考价值。

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的新语法,要使用新的语法,只需要做两步简单的替换:

    1.把@asyncio.coroutine替换为async;
    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的主要内容,如果未能解决你的问题,请参考以下文章

异步 IO 的整洁代码

Python异步IO

Cypress.io 如何处理异步代码

如何用python实现异步io

非阻塞IO可以等同异步IO嘛?

ES7-Es8 js代码片段