廖雪峰教程之学习笔记_webapp实战项目_从协程到异步IO到aiohttp

来看看,如何从协程发展到异步IO又是如何使用的aiohttp框架的。、

一、协程(coroutine)

1、协程的功能:

普通子程序调用总是一个入口,一个出口,调用顺序是固定的。

def A():
    print('1')
    print('2')
    print('3')

普通子程序,肯定是执行“打印1、2、3”这样的顺序,中间不会中断。

但是如果执行的是比较费事的操作,比如访问网络、向磁盘写入文件 等,CPU实际上是空闲的。为了充分利用CPU的性能,也为了实现单核CPU的并发操作,产生了协程。

2·协程的例子(生产者-消费者模型):

def consumer():                                    #接收者,并且是一个generator
    r = ''
    while True:
        n = yield r                                #接收调用者发出的一个参数r
        if not n:
            return
        print('[CONSUMER] Consuming %s...' % n)
        r = '200 OK'

def produce(c):                                      #调用者
    c.send(None)                                     #第一次调用必须send(None)启动generator
    n = 0
    while n < 5:
        n = n + 1
        print('[PRODUCER] Producing %s...' % n)
        r = c.send(n)                                #发出n(切换到comsumer执行,从yield r之后执行)
        print('[PRODUCER] Consumer return: %s' % r)
    c.close()

c = consumer()
produce(c)

二、异步IO

1、为什么异步IO

同步IO就是在进行IO操作时,主线程要等IO操作的结束,但是IO操作一般都很慢。所以,产生了异步IO,IO操作接着操作,主线程接着执行,等IO操作结束,给主线程返回个消息就可以了 。

2、asyncio

asyncio是Python 3.4版本引入的标准库,直接内置了对异步IO的支持。

asyncio的编程模型就是一个消息循环。(**********************************这句并不是很理解***************************)

a)使用方法

asyncio模块中直接获取一个EventLoop的引用,然后把需要执行的协程扔到EventLoop中执行,就实现了异步IO。

b)例:

扫描二维码关注公众号,回复: 1620689 查看本文章
import asyncio

@asyncio.coroutine
def hello():
    print("Hello world!")
    # 异步调用asyncio.sleep(1):
    r = yield from asyncio.sleep(1)                #yield from调用一个generator,asyncio.sleep(1) 可替换成IO操作
    print("Hello again!")

# 获取EventLoop:
loop = asyncio.get_event_loop()
# 执行coroutine
loop.run_until_complete(hello())
loop.close()

hello()函数通过@asyncio.coroutine标记成coroutine。yield from 调用asyncio.sleep(1)的返回值,因为asyncio.sleep(1)是一个coroutine,因此线程不会等待结果,把这个hello()中断,接着执行下一个循环。

消息循环中...

asyncio.sleep(1)执行完毕了,结果返回了。中断的hello()函数接着执行。

三、aiohttp

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)                       #创建webapp
    app.router.add_route('GET', '/', index)                #增加路由:'GET'类请求,url=='/',就调用index函数        
    app.router.add_route('GET', '/hello/{name}', hello)    #增加路由:'GET'类请求,url=='/hello/{name}'',就调用hello函数   
    srv = await loop.create_server(app.make_handler(), '127.0.0.1', 8000)    #创建server,在'127.0.0.1'IP, 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(





猜你喜欢

转载自blog.csdn.net/bird333/article/details/80659119