首頁 >後端開發 >Python教學 >python gevent實作機制

python gevent實作機制

巴扎黑
巴扎黑原創
2016-12-09 14:38:401326瀏覽

之前看的greenlet只是提供了基本的coroutine的作用,是最小的執行單元.但是要想使用,還需要提供一個調度器,來調度什麼時候哪些greenlet應該執行.所以看了一下gevent的實現,當前的穩定版本使用的是libev.libevent的替代方案.性能上更優越一些.libev支援很多事件類型,但是最常用的是io和timer類型的.io類型的通過系統提供的相關係統調用實現( linux下是epoll),timer類型的通過維護一個最小堆實現. 
看一下下面的代碼: 

Python代碼  

import gevent  
from gevent import monkey  
monkey.patch_all()  
  
def download():  
    import urllib2  
    urllib2.urlopen('http://www.google.com/').read()  
  
c = gevent.spawn(download)  
gevent.joinall([c])

gevent通過spawn創建並啟動一個greenlet,此greenlet執行函數為download.greenk是透過把這個greenlet加入到libev的prepare callback裡面.libev在每次執行事件循環的時候都會調用prepare callback裡面的函數,執行後把裡面的callback清除掉.這樣就能保證每次spawn的greenlet有執行的機會.並且只會執行一次. 
在這個greenlet執行urlopen以及read的時候,因為涉及到io操作(socket.[send|recv]),gevent透過monkey patch把這些函數進行了封裝,當呼叫相關的操作時就會建立一個對應fd的watcher加入libev的事件清單裡面. 
當有相關的讀寫事件發生時,會觸發對應的callback.相關的callback會呼叫greenlet的switch進行coroutine的切換. 
透過上面的方式greenlet達到了調度器的目的.


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn