python Gevent – 高性能的Python并发框架
話說gevent也沒個logo啥的,于是就擺了這張圖= =|||,首先這是一種叫做greenlet的鳥,而在python里,按照官方解釋greenlet是輕量級的并行編程,而gevent呢,就是利用greenlet實現的基于協程的python的網絡library,好了,關系理清了。。。
話說pycon沒有白去阿,了解了很多以前不知道的東西,比如說協程,gevent,greenlet,eventlet。說說協程,進程和線程大家平時了解的都比較多,而協程算是一種輕量級進程,但又不能叫進程,因為操作系統并不知道它的存在。什么意思呢,就是說,協程像是一種在程序級別來模擬系統級別的進程,由于是單進程,并且少了上下文切換,于是相對來說系統消耗很少,而且網上的各種測試也表明,協程確實擁有驚人的速度。并且在實現過程中,協程可以用以前同步思路的寫法,而運行起來確是異步的,也確實很有意思。話說有一種說法就是說進化歷程是多進程->多線程->異步->協程,暫且不論說的對不對,單從諸多贊譽來看,協程還是有必要理解一下的。
比較慚愧,greenlet沒怎么看就直接看gevent,官方文檔還是可以看看的,尤其是源碼里的examples都相當不錯,有助于理解gevent的使用。
gevent封裝了很多很方便的接口,其中一個就是monkey
這樣兩行,就可以使用python以前的socket之類的,因為gevent已經給你自動轉化了,真是超級方便阿。
而且安裝gevent也是很方便,首先安裝依賴libevent和greenlet,再利用pypi安裝即可
然后,gevent中的event,有wait,set等api,方便你可以讓某些協程在某些地方等待條件,然后用另一個去喚醒他們。
再就是gevent實現了wsgi可以很方便的當作python的web server服務器使。
最后放送一個我利用gevent實現的一個帶有緩存的dns server
這個是直接利用了dict來作為緩存查詢了,在這里還有我將dict換成redis持久化實現的另一個版本(話說redis的python api也可以利用pypi安裝,pypi(PyPI?- the Python Package Index : Python Package Index)這真是個好東西阿),話說可以將這段代碼放到國外的服務器上去運行,然后修改dns的地址去指向它,然后你懂的。。。
##################################
gevent相關,請去官網http://pypi.python.org/pypi/gevent#downloads下載gevent模塊
程序及注釋如下:
# -*- coding: cp936 -*-
import gevent?
import time
from gevent import event #調用gevent的event子模塊
#三個進程需要定義三個事件event1,event2,event3,來進行12,23,31循環機制,即進程一,進程二,進程三順序執行
def fun1(num,event1,event2):#固定格式
??? i=0
??? while i<10: #設置循環10次
??????? i+=1
??????? time.sleep(1) #睡眠1秒
??????? print'進程一:111111111'
??????? event2.set() #將event2值設為True
??????? event1.clear()#將event1值設為False
??????? event1.wait()#event1等待,其值為True時才執行
????????
def fun2(num,event2,event3):
??? i=0
??? while i<10:
??????? i+=1
??????? time.sleep(1)
??????? print'進程二:222222222'
??????? event3.set()#將event3值設為True
??????? event2.clear()#將event2值設為False
??????? event2.wait()#event2等待,其值為True時才執行
def fun3(num,event3,event1):
??? i=0
??? while i<10:
??????? i+=1
??????? time.sleep(1)
??????? print'進程三:333333333'
??????? event1.set()
??????? event3.clear()
??????? event3.wait()
if __name__=="__main__": #執行調用格式
??? act1=gevent.event.Event() #調用event中的Event類,用act1表示
??? act2=gevent.event.Event()?
??? act3=gevent.event.Event()
??? #三個進程,act1,act2,act3
??? Gevents=[] #建立一個數列,用來存和管理進程
??? g=gevent.Greenlet(fun1,1,act1,act2) #調用gevent中的Greenlet子模塊,用Greenlet創建進程一
??? g.start()?
??? print'進程一啟動:'
??? Gevents.append(g) #將進程一加入到Gevents數列
??? g=gevent.Greenlet(fun2,2,act2,act3)
??? g.start()
??? print'進程二啟動:'
??? Gevents.append(g)
??? g=gevent.Greenlet(fun3,3,act3,act1)
??? g.start()
??? print'進程三啟動:'
??? print'所有進程都已啟動!'
??? Gevents.append(g)
??? gevent.joinall(Gevents) #調用Greenlet中的joinall函數,將Gevents的進程收集排列
##################################
看看Gevent。
您可以創建幾個 Greenlet 對象為幾個任務。
每個 greenlet 是綠色的線程。
##################################
關于gevent
首先,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處理,就把阻塞的部分改為異步吧。
##################################
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 的任務池
[python]?view plain?copy
以上內容轉自互聯網:http://www.coder4.com/archives/1522
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的python Gevent – 高性能的Python并发框架的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ASP.NET处理架构
- 下一篇: 磁盘 I/O 的概念