http 協程與非同步 Python

2022-09-07 05:18:13 字數 2468 閱讀 4542

===協程是啥===

簡單來說,協程是一種基於執行緒之上,但又比執行緒更加輕量級的存在。對於系統核心來說,協程具有不可見的特性,所以這種由 程式設計師自己寫程式來管理的輕量級執行緒又常被稱作 "使用者空間執行緒"。

===協程比多執行緒好在哪===

適用場景:協程適用於被阻塞的,且需要大量併發的場景。

不適用場景:協程不適用於存在大量計算的場景(因為協程的本質是單執行緒來回切換),如果遇到這種情況,還是應該使用其他手段去解決。

相信用過 python 切做過爬蟲和介面測試的人都對 requests 庫不陌生。requests 中實現的 http 請求是同步請求,但其實基於 http 請求 io 阻塞的特性,非常適合用協程來實現 "非同步" http 請求從而提公升測試效率。 

於是在 github 經過了一番探索後,果不其然,最終尋找到了支援協程 "非同步" 呼叫 http 的開源庫:httpx。

httpx是乙個幾乎繼承了所有 requests 的特性並且支援 "非同步" http 請求的開源庫。簡單來說,可以認為 httpx 是強化版 requests。

安裝:pip install httpx

單執行緒同步http請求耗時:

請求狀態碼

8print(f'

函式async_main當前執行緒: 請求次數 + 狀態碼 ')

910#開始時間

11 starttime =time.time()12#

開始執行函式

13 [async_main(url='

', time=i) for i in range(20)] #

測試20次

14 endtime =time.time()

1516

print('

總耗時為:

', endtime-starttime)

輸出結果為:

沒有意外,單執行緒順序同步請求。

接下來是單執行緒「非同步」請求:

非同步請求78

#主函式

9 async def

async_main(url, time):

10 response = await client.get(url) #

呼叫client請求url

11 status_code = response.status_code #

請求狀態碼

12print(f'

函式async_main當前執行緒: 請求次數 + 狀態碼')

1314 loop = asyncio.get_event_loop() #

獲取事件15#

print(loop) #

1617

#建立任務

18 tasks = [async_main(url='

', time=i) for i in range(20)] #

還是搞20次

19 starttime = time.time() #

開始時間

20 loop.run_until_complete(asyncio.wait(tasks)) #

非同步事件一直執行,直至tasks裡的任務完成

21 endtime = time.time() #

結束事件

22 loop.close() #

關閉時間迴圈

23print('

總耗時為:

', endtime-starttime)

輸出結果如下:

非同步快還是快的,總耗時將近是同步的10分1。可以看到順序雖然是亂的16,18,1... ,這是因為程式在協程間不停切換, 但是主線程並沒有切換 ,協程本質還是單執行緒 。

python協程與非同步協程

在前面幾個部落格中我們一一對應解決了消費者消費的速度跟不上生產者,浪費我們大量的時間去等待的問題,在這裡,針對業務邏輯比較耗時間的問題,我們還有除了多程序之外更優的解決方式,那就是協程和非同步協程。在引入這個概念之前我們先看 看這個圖 從這個我們可以看出來,假如來了9個任務,即使我們開了多程序,在業...

python 非同步與協程學習

參考 深入理解python非同步程式設計 理解 python asyncio 1 非同步非租塞 以春運火車票為例,非同步 你使用分流軟體搶票,設定好時間型別,軟體自動執行 非阻塞 你不用等搶票結果,可以去做別的事 如何獲得結果 輪詢 每隔一段時間,你看一下搶到票沒有 事件通知 設定搶到票,郵件或者簡...

關於python協程與非同步舉例

寫了幾個介面,也就接觸到了python的非同步。python的協程使用非同步實現的 說法不知道準不準確 所以直接使用協程來做,看的很多例子也是這麼幹的 先看 import json import tornado import tornado.web from tornado import gen f...