天天看點

python Gevent – 高性能的Python并發架構 關于gevent gevent注意事項

話說gevent也沒個logo啥的,于是就擺了這張圖= =|||,首先這是一種叫做greenlet的鳥,而在python裡,按照官方解釋greenlet是輕量級的并行程式設計,而gevent呢,就是利用greenlet實作的基于協程的python的網絡library,好了,關系理清了。。。

gevent封裝了很多很友善的接口,其中一個就是monkey

這樣兩行,就可以使用python以前的socket之類的,因為gevent已經給你自動轉化了,真是超級友善阿。

而且安裝gevent也是很友善,首先安裝依賴libevent和greenlet,再利用pypi安裝即可

然後,gevent中的event,有wait,set等api,友善你可以讓某些協程在某些地方等待條件,然後用另一個去喚醒他們。

再就是gevent實作了wsgi可以很友善的當作python的web server伺服器使。

最後放送一個我利用gevent實作的一個帶有緩存的dns server

##################################

程式及注釋如下:

您可以建立幾個 greenlet 對象為幾個任務。

首先,gevent是一個網絡庫:libevent是一個事件分發引擎,greenlet提供了輕量級線程的支援。是以它不适合處理有長時間阻塞io的情況。

gevent就是基于這兩個東西的一個專門處理網絡邏輯的并行庫。

1. gevent.spawn啟動的所有協程,都是運作在同一個線程之中,是以協程不能跨線程同步資料。

2. gevent.queue.queue 是協程安全的。

3. gevent啟動的并發協程,具體到task function,不能有長時間阻塞的io操作。因為gevent的協程的特點是,目前協程阻塞了才會切換到别的協程。

如果目前協程長時間阻塞,則不能顯示(gevent.sleep(0),或隐式,由gevent來做)切換到别的協程。導緻程式出問題。

4. 如果有長時間阻塞的io操作,還是用傳統的線程模型比較好。

5. 因為gevent的特點總結是:事件驅動+協程+非阻塞io,事件驅動值得是libvent對epool的封裝,來基于事件的方式處理io。

協程指的是greenlet,非阻塞io指的是gevent已經patch過的各種庫,例如socket和select等等。

6. 使用gevent的協程,最好要用gevent自身的非阻塞的庫。如httplib, socket, select等等。

7. gevent适合處理大量無阻塞的任務,如果有實在不能把阻塞的部分變為非阻塞再交給gevent處理,就把阻塞的部分改為異步吧。

1. gevent.server.streamserver 會針對每個用戶端連接配接啟動一個greenlet處理,要注意的是,如果不循環監聽( 阻塞在read ),

每個greenlet會在完成後立即退出,進而導緻用戶端退出( 發送fin_ack給用戶端 )。這個問題折騰了一晚上,終于弄明白了。坑爹啊。。

2. 要非常仔細的檢查,greenlet處理的代碼,發現有可能阻塞io的地方,盡量用gevent提供的庫。

3. 一些第三方庫隐藏了自己的實作( 通常是直接封裝c庫),要使得gevent相容它們,可以用monkey_patch,但不保證全部管用。

4. 最後最後的一點,gevent的greenlet性能非常高,是以如果是用它作為并發的client端,那麼一定要注意,你的server端處理速度一定要足夠快!

否則你的用戶端代碼會因為服務端的慢速,而失去了greenlet的優勢。。。

####################################

安裝 libevent:apt-get install libevent-dev

安裝python-dev:apt-get install python-dev

安裝greenlet:easy_install greenlet

安裝gevent:easy_install gevent

一個小測試,測試gevent 的任務池