python之异步IO

Posted

tags:

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

协程的用武之地

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

  • 协程其实就是单线程在调度,是无法利用多核CPU,所以对于计算密集型的任务还是需要考虑多进程+协程的方式。

参考:

  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。

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

 

报异常了:

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

以上问题不知道是不是因为版本问题?待解决...........

 


以上是关于python之异步IO的主要内容,如果未能解决你的问题,请参考以下文章

Python异步编程之web框架 异步vs同步 文件IO任务压测对比

python之异步select解析

python之异步select解析

Python并发编程之学习异步IO框架:asyncio 中篇

{python之IO多路复用} IO模型介绍 阻塞IO(blocking IO) 非阻塞IO(non-blocking IO) 多路复用IO(IO multiplexing) 异步IO

python学习过程之IO编程