(一)asyncio 1、asyncio 用async 修飾詞來聲明非同步函數 2、asyncio.create_task(非同步函數)來創建任務 3、通過await asyncio.gather(任務)來執行任務 4、通過asyncio.run(函數)來觸發運行 5、一個比較好的方式是asyncio. ...
(一)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)過程,直到所有任務處理完畢。