(一)asyncio
1、asyncio 用async 修饰词来声明异步函数
2、asyncio.create_task(异步函数)来创建任务
3、通过await asyncio.gather(任务)来执行任务
4、通过asyncio.run(函数)来触发运行
5、一个比较好的方式是asyncio.run(main())作为程序入口,在程序运行周期内,只调用一次asyncio.run()
例如:请求5次这个url https://www.java.com/zh_CN/
用协程是3.8s,不用协程9.2s。当然这个时间对比可能不是非常准确,因为请求过程还受其他因素影响,不过应该能大致说明问题。
1 import datetime
2
3 import asyncio
4 import aiohttp
5
6 header = {
7 "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36",
8 "Host":"c.oracleinfinity.io",
9 "Accept-Encoding":"gzip, deflate, br",
10 "accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
11 }
12 async def fetch_content(url):
13 async with aiohttp.ClientSession(
14 headers=header,connector=aiohttp.TCPConnector(ssl=False)
15 ) as session:
16 async with session.get(url) as response:
17 return await response.text()
18
19 async def main():
20 url = "https://www.java.com/zh_CN/"
21 urls = [url for i in range(5)]
22 tasks = [asyncio.create_task(fetch_content(url)) for url in urls]
23 pages = await asyncio.gather(*tasks) #*表示解包列表,解包字典则用2个星号**
24
25
26 start_time = datetime.datetime.now()
27 print(start_time)
28 asyncio.run(main())
29 end_time = datetime.datetime.now()
30 print(end_time - start_time)
不用协程
import requests import datetime
header = {
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36",
"Host":"c.oracleinfinity.io",
"Accept-Encoding":"gzip, deflate, br",
"accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.9"
}def main():
url = "https://www.java.com/zh_CN/"
for i in range(5):
page = requests.get(url,headers=header).content
start_time = datetime.datetime.now()
print(start_time)
main()
end_time = datetime.datetime.now()
print(end_time - start_time)
对协程的理解:
例如:小明是一个客服,现在有5个用户同时像他咨询问题。(可以抽象为5个任务)
普通的处理方式是:
1、先完全解决用户1的疑问。(完成任务1)
2、直到用户1回复说没疑问了,再去解决用户2的疑问(完成任务2)
。。。。重复这个过程,直到解决完5个用户的疑问。
协程的处理方式是:
1、回复用户1 。
2、等待用户1回复的过程中,去回复用户2
3、等待用户2回复的过程中,去回复用户3.
4、用户1回复了,继续回复用户1
.......重复这个过程,直到解答完5个用户的疑问。
总之,
1、普通的处理方式就是5个任务依次执行,直到执行完成所有任务。
2、而协程的处理方式是。
(1)任务遇到阻塞(需要等待)的地方时,调度器会去执行其他任务
(2)当需要等待的部分处理完成后,会告诉调度器,我执行完了。然后调度器会继续执行这个任务后续的部分。
(3)重复(1)、(2)过程,直到所有任务处理完毕。