import asyncio
import requests
#定义协程
async def execute(x):
"""
async定义的方法会成为无法直接执行的coroutine对象,必须将其
注册到事件循环中才能执行
task是对coroutine对象的进一步封装。
:param x:
:return:
"""
print("Number:",x)
coroutine = execute(1)
print("Coroutine:",coroutine)
print("After calling execute")
loop = asyncio.get_event_loop()
loop.run_until_complete(coroutine) #将coroutine封装为task对象
"""
#显式封装
task = loop.create_task(coroutine)
loop.run_until_complete(task)
print("Task:",task)
"""
print("After calling loop")
#回调
async def request():
url = "https://www.baidu.com"
status = requests.get(url)
return status
def callback(task):
print("status: ",task.result())
coro =request()
task = asyncio.ensure_future(coro)
task.add_done_callback(callback) #将callback方法传递给封装好的task对象
print("Task: ",task)
loop = asyncio.get_event_loop()
loop.run_until_complete(task)
print("Task: ",task)
"""
不定义callback函数,直接掉results方法也可获取结果
print("results:",task.result())
"""
多任务协程
如果我们想执行多次请求应该怎么办呢?我们可以定义一个 task 列表,然后使用 asyncio 的 wait() 方法即可执行,看下面的例子:
tasks = [asyncio.ensure_future(request()) for _ in range(5)]#创建任务列表,然后传给wait方法,
print("Tasks",tasks)
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))
for task in tasks:
print("Task Result:",task.result())
协程实现
""
定义了一个 Flask 服务,主入口是 index() 方法,方法里面先调用了 sleep() 方法休眠 3 秒,然后接着再返回结果,
也就是说,每次请求这个接口至少要耗时 3 秒,这样就模拟了一个慢速的服务接口。
"""
app = Flask(__name__)
@app.route('/')
def index():
time.sleep(3)
return "Hello!"
if __name__ =='__main__':
app.run(threaded=True) #表明flask启用了多线程模式
以上程序运行后,下面程序再运行
import time
import aiohttp
import requests
import asyncio
start = time.time()
async def get(url):
return requests.get(url)
async def reque():
url = 'http://127.0.0.1:5000'
print("Waiting for",url)
response = await get(url)
print("Get response from",url,'request:',response.text)
tasks = [asyncio.ensure_future(reque()) for _ in range(5)]
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))
end = time.time()
print('Cost time:',end-start)
耗时15s
"""
它还不是异步执行,也就是说我们仅仅将涉及 IO 操作的代码封装到 async 修饰的方法里面是不可行的!
我们必须要使用支持异步操作的请求方式才可以实现真正的异步,所以这里就需要 aiohttp 派上用场了。
"""
使用aiohttp
import time
import requests
import asyncio
import aiohttp
start = time.time()
async def get(url):
session = aiohttp.ClientSession()
print("session类型:",type(session))
response = await session.get(url)
result = await response.text()
session.close()
return result
async def reque():
url = 'http://127.0.0.1:5000'
print("Waiting for",url)
result = await get(url)
#await可以将耗时等待的操作挂起,让出控制权 await 后面可以跟一个 coroutine 对象
print("Get response from",url,'request:',result)
tasks = [asyncio.ensure_future(reque()) for _ in range(5)]
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))
end = time.time()
print('Cost time:',end-start)
耗时四秒
与单进程 多线程比较
参考:https://blog.csdn.net/qq_42156420/article/details/81138062