在执行某些IO密集型任务的时候,程序常常会因为等待 IO 而阻塞。为解决这一问题,可以考虑使用python中的协程异步。
从 Python 3.4 开始,Python 中加入了协程的概念,但这个版本的协程还是以生成器对象为基础的,在 Python 3.5 则增加了关键字async/await,使得协程的实现更加方便,本文中通过async/await 来实现协成。
python中使用协程最常用的库是asyncio,可以帮我们检测IO(只能是网络IO【HTTP连接就是网络IO操作】),实现应用程序级别的切换(异步IO)。
要实现真正的异步,必须要使用支持异步操作的请求方式。aiohttp 是一个支持异步请求的库,利用它和 asyncio 配合我们可以非常方便地实现异步请求操作。
安装: pip3 install aiohttp
官方文档链接为:https://aiohttp.readthedocs.io/
# coding:utf-8
import time
from flask import Flask
app = Flask(__name__)
@app.route(‘/‘)
def index():
time.sleep(3)
return ‘hello world‘
if __name__ == ‘__main__‘:
app.run(threaded=True) #开启多线程模式
该服务器3秒后才做出响应。
# coding:utf-8
import asyncio
import time
import aiohttp
start_time = time.time()
async def request():
url = "http://127.0.0.1:5000/"
result = await get(url) #await将耗时等待的操作挂起,让出控制权
print(result)
async def get(url):
session = aiohttp.ClientSession()
response = await session.get(url)
result = await response.read() #返回bytes类型
# result = await response.text() #返回str类型
await session.close()
return result
tasks = [asyncio.ensure_future(request()) for _ in range(5)] #创建5个task
loop = asyncio.get_event_loop() #创建事件循环对象
loop.run_until_complete(asyncio.wait(tasks)) #task列表传给 wait()方法并注册到事件循环中执行。
end_time = time.time()
print(‘花费时间:{}秒‘.format(end_time-start_time))
b‘hello world‘
b‘hello world‘
b‘hello world‘
b‘hello world‘
b‘hello world‘
花费时间:3.0151724815368652秒
运行时间在3秒左右,如果采用同步,则需要15秒左右,速度提升非常可观。尤其对于成百上千的任务来说,效果更为明显。
原文:https://www.cnblogs.com/eliwang/p/14815596.html