Asynchronous IO
Example:
# !/usr/bin/env python3
# -*- coding: utf-8 -*-
# standard wihtout AIO
"""
from timeit import default_timer
import aiohttp
import asyncio
import requests
def load_session(delay):
print(f'Starting the delay {delay}s session...')
txt = requests.get(f'https://httpbin.org/delay/{delay}').text
print(f'Ended the delay {delay}s session')
return txt
def run_demo():
start_time = default_timer()
delay1 = load_session(2)
delay2 = load_session(3)
total_time = default_timer() - start_time
print(f'We totally used {total_time:.2f}s')
print('session1: ' + delay1)
print('session2: ' + delay2)
def main():
run_demo()
if __name__ == '__main__':
main()
"""
# Use AIO
from timeit import default_timer
import asyncio
import aiohttp
async def load_session(session, delay):
print(f'Starting the delay {delay}s session...')
async with session.get(f'https://httpbin.org/delay/{delay}') as resp:
txt = await resp.text()
print(f'Ended the delay {delay}s session')
return txt
async def main():
start_time = default_timer()
async with aiohttp.ClientSession() as session:
delay1 = asyncio.create_task(load_session(session, 2))
delay2 = asyncio.create_task(load_session(session, 3))
await asyncio.sleep(1)
print('Doing other things...')
txt1 = await delay1
txt2 = await delay2
elapsed_time = default_timer() - start_time
print(f'Totally used {elapsed_time:.2}s')
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Starting the delay 2s session...
Starting the delay 3s session...
Doing other things...
Ended the delay 2s session
Ended the delay 3s session
Totally used 6.6s
小坑
如果上面的例子使用最后的部分使用asyncio.run(main())
来执行代码,结果依然可以输出,但是会产生下面的报错RuntimeError('Event loop is closed')
,
产生的原因是因为前面产生的asyncio的task没有做善后处理,所以code调用self.close()关掉了,改用如下可以解决:
loop = asyncio.get_event_loop()
loop.run_until_complete(main())