异步IO
协程
Python的协程是通过迭代器实现的
yield关键字不但可以返回一个值,还可以接收调用者发出的参数
- 首先调用c.send(None)启动生成器
- 然后,一旦生产了东西,通过c.send(n)切换到consumer执行
- consumer通过yield拿到消息,处理,又通过yield把结果传回
- produce拿到consumer处理的结果,继续生产下一条消息
- produce决定不生产了,通过c.close()关闭consumer,整个过程结束
def consumer():
result = ''
while True:
params = yield result
if not params:
return
print('消费者执行任务%s' % params)
result = '消费者任务%s的执行成功' % (params)
def produce(c):
c.send(None)
for n in range(1, 5):
print("生产者分发任务%s" % n)
result = c.send(n)
print("生产者收到了%s" % result)
c.close()
c = consumer()
produce(c)
asyncio
asyncio的编程模型就是一个消息循环。我们从asyncio模块中直接获取一个EventLoop的引用,然后把需要执行的协程扔到EventLoop中执行,就实现了异步IO
import asyncio
async def hello():
print("Hello world!")
# 异步调用asyncio.sleep(1)
# 执行到这里不会等待,会执行EventLoop中其他可以执行coroutine
r = await asyncio.sleep(1)
print("Hello again!")
# 获取EventLoop
loop = asyncio.get_event_loop()
# 执行coroutine
loop.run_until_complete(asyncio.wait([hello(), hello()]))
loop.close()
aiohttp
asyncio实现了TCP、UDP、SSL等协议,aiohttp是基于asyncio实现的HTTP框架
import asyncio
from aiohttp import web
async def index(request):
await asyncio.sleep(0.5)
return web.Response(body=b'<h1>hello world</h1>', content_type='text/html')
async def init():
app = web.Application()
app.router.add_route('GET', '/', index)
runner = web.AppRunner(app)
await runner.setup()
site = web.TCPSite(runner, '127.0.0.1', 8000)
print('Server started at http://127.0.0.1:8000...')
await site.start()
loop = asyncio.get_event_loop()
loop.run_until_complete(init())
loop.run_forever()