摘要:我們知道對于網絡請求這種的場景來說,最怕的就是某個請求阻塞了其余的操作,讓并發性大大降低。同步首先我們來看看傳統的請求。結論我又多試了幾次,的效率確實牛,遠遠高于同步請求。
我們知道對于網絡請求這種IO bound的場景來說,最怕的就是某個請求阻塞了其余的操作,讓并發性大大降低。今天就來介紹一款python下的并發庫-gevent。
首先看一下他自己的介紹:
gevent是一個基于libev的并發庫。它為各種并發和網絡相關的任務提供了整潔的API。
嗯,確實很簡潔,很易使用。待會我們就見識到了。
同步IO首先我們來看看傳統的IO請求。
比如我們請求:http://httpbin.org/ip 發個http get請求會得到我們的ip地址,如:
{ "origin": "183.240.202.14" }
我們來寫個腳本連續發50個get請求到這個地址,以模擬多個請求。(腳本命名為get.py)
import requests url = "http://httpbin.org/ip" for i in range(50): print("{}: {}".format(i, requests.get(url).text))
統計一下運行時間:
$ time python3 get.py (輸出略...) python3 get.py 0.56s user 0.06s system 1% cpu 35.606 total
大概花費35s鐘,當然不同網絡環境可能結果不同。而且打印出來的結果是按照1, 2, 3...50這樣的順序來的,說明整個請求是同步的,一個請求結束再發下一個請求。
使用gevent我們再來寫一個gevent版的get.py,命名為gevent_get.py
import requests import gevent import gevent.monkey # 這里將socket變成異步 gevent.monkey.patch_socket() url = "http://httpbin.org/ip" def hello(i): print("{}: {}".format(i, requests.get(url).text)) tasks = [gevent.spawn(hello, i) for i in range(50)] gevent.joinall(tasks)
再來看看運行時間:
$ time python3 gevent_get.py (輸出略...) python3 gevent_get.py 0.49s user 0.06s system 39% cpu 1.403 total
我的天!才1.4秒左右,而且打印出來的結果沒有按照1, 2, 3...50這樣排列,而是按照隨機順序排列的,說明整個請求是異步非阻塞的。
結論我又多試了幾次,gevent的效率確實牛,遠遠高于同步io請求。最近在我的一個爬蟲小項目里面用進程池 + gevent,爬取80個頁面,大概花費40s左右,每個頁面只要0.5s,而且還包括DOM解析的時間,而用同步請求則花費大概300s左右。
gevent的更多用法請參考其官方文檔。這么簡單又好用的庫趕緊試試吧。^_^
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/45515.html
摘要:所以與多線程相比,線程的數量越多,協程性能的優勢越明顯。值得一提的是,在此過程中,只有一個線程在執行,因此這與多線程的概念是不一樣的。 真正有知識的人的成長過程,就像麥穗的成長過程:麥穗空的時候,麥子長得很快,麥穗驕傲地高高昂起,但是,麥穗成熟飽滿時,它們開始謙虛,垂下麥芒。 ——蒙田《蒙田隨筆全集》 上篇論述了關于python多線程是否是雞肋的問題,得到了一些網友的認可,當然也有...
摘要:一旦有事件產生可能是一次出現好多個事件,就會按照優先級依次調用每個事件的回調函數。注意,是有超時的,所以一些無法以文件描述符的形式存在的事件也可以有機會被觸發。 這一篇主要想跟大家分享一下 Gevent 實現的基礎邏輯,也是有同學對這個很感興趣,所以貼出來跟大家一起分享一下。 Greenlet 我們知道 Gevent 是基于 Greenlet 實現的,greenlet 有的時候也被...
摘要:并發的方式有多種,多線程,多進程,異步等。多線程和多進程之間的場景切換和通訊代價很高,不適合密集型的場景關于多線程和多進程的特點已經超出本文討論的范疇,有興趣的同學可以自行搜索深入理解。 編程中,我們經常會遇到并發這個概念,目的是讓軟件能充分利用硬件資源,提高性能。并發的方式有多種,多線程,多進程,異步IO等。多線程和多進程更多應用于CPU密集型的場景,比如科學計算的時間都耗費在CPU...
摘要:事件循環是異步編程的底層基石。對事件集合進行輪詢,調用回調函數等一輪事件循環結束,循環往復。協程直接利用代碼的執行位置來表示狀態,而回調則是維護了一堆數據結構來處理狀態。時代的協程技術主要是,另一個比較小眾。 Coding Crush Python開發工程師 主要負責豈安科技業務風險情報系統redq。 引言 1.1. 存儲器山 存儲器山是 Randal Bryant 在《深入...
摘要:隨著我們對于效率的追求不斷提高,基于單線程來實現并發又成為一個新的課題,即只用一個主線程很明顯可利用的只有一個情況下實現并發。作為的補充可以檢測操作,在遇到操作的情況下才發生切換協程介紹協程是單線程下的并發,又稱微線程,纖程。 引子 之前我們學習了線程、進程的概念,了解了在操作系統中進程是資源分配的最小單位,線程是CPU調度的最小單位。按道理來說我們已經算是把cpu的利用率提高很多了。...
閱讀 2337·2021-11-16 11:52
閱讀 2323·2021-11-11 16:55
閱讀 750·2021-09-02 15:41
閱讀 2981·2019-08-30 15:54
閱讀 3142·2019-08-30 15:54
閱讀 2252·2019-08-29 15:39
閱讀 1507·2019-08-29 15:18
閱讀 968·2019-08-29 13:00