python之gevent(1)

????因為python線程的性能問題,在python中使用多線程運行代碼經常不能達到預期的效果。而有些時候我們的邏輯中又需要開更高的并發(fā),或者簡單的說唆樊,就是讓我們的代碼跑的更快,在同樣時間內執(zhí)行更多的有效邏輯刻蟹、減少無用的等待逗旁。gevent就是一個現在很火、支持也很全面的python第三方協(xié)程庫舆瘪。
????gevent是python的一個并發(fā)框架片效,以微線程greenlet為核心,使用了epoll事件監(jiān)聽機制以及諸多其他優(yōu)化而變得高效英古。而且其中有個monkey類淀衣,將現有基于Python線程直接轉化為greenlet(類似于打patch)。在運行時的具體流程大概就是:
????當一個greenlet遇到IO操作時召调,比如訪問網絡/睡眠等待膨桥,就自動切換到其他的greenlet,等到IO操作完成唠叛,再在適當的時候切換回來繼續(xù)執(zhí)行只嚣。由于IO操作非常耗時,經常使程序處于等待狀態(tài)艺沼,有了gevent為我們自動切換協(xié)程册舞,就保證總有greenlet在運行,而不是等待IO障般。同時也因為只有一個線程在執(zhí)行环础,會極大的減少上下文切換的成本。

gevent基本使用

# -*- coding: utf-8 -*-

import gevent


def f1():
    for i in range(5):
        print 'run func: f1, index: %s ' % i
        gevent.sleep(0)


def f2():
    for i in range(5):
        print 'run func: f2, index: %s ' % i
        gevent.sleep(0)


t1 = gevent.spawn(f1)
t2 = gevent.spawn(f2)
gevent.joinall([t1, t2])

運行后輸出如下圖所示:


image.png

????由圖中可以看出剩拢,f1和f2是交叉打印信息的,因為在代碼執(zhí)行的過程中饶唤,我們人為使用gevent.sleep(0)創(chuàng)建了一個阻塞徐伐,gevent在運行到這里時就會自動切換函數切換函數。也可以在執(zhí)行的時候sleep更長時間募狂,可以發(fā)現兩個函數基本是同時運行然后各自等待办素。

????在實際運用的過程中,我們如果有需要通過人為sleep來增加時間間隔或者確保部分邏輯安全的時候祸穷,此處使用就很方便了性穿。當然,更多時候我們還是在需要進行網絡請求的時候使用gevent:

# -*- coding: utf-8 -*-

from gevent import monkey; monkey.patch_all()
import gevent
import requests
from datetime import datetime


def f(url):
    print 'time: %s, GET: %s' % (datetime.now(), url)
    resp = requests.get(url)
    print 'time: %s, %d bytes received from %s.' % (
        datetime.now(), len(resp.text), url)


gevent.joinall([
        gevent.spawn(f, 'https://www.python.org/'),
        gevent.spawn(f, 'https://www.yahoo.com/'),
        gevent.spawn(f, 'https://github.com/'),
])

運行上述代碼雷滚,結果如下:


image.png

由上圖可以看出需曾,程序基本在同一時間觸發(fā)了對三個網站的請求,然后各自進行,分別結束呆万。也就是當gevent發(fā)現阻塞之后商源,讓當前急需執(zhí)行,然后自動切換到了另外的請求中運行谋减。

加鎖

如果需要在使用gevent的時候加鎖牡彻,也是非常方便的:

# -*- coding: utf-8 -*-

import gevent
from gevent.lock import Semaphore

sem = Semaphore(1)


def f1():
    for i in range(5):
        sem.acquire()
        print 'run f1, this is ', i
        sem.release()
        gevent.sleep(1)


def f2():
    for i in range(5):
        sem.acquire()
        print 'run f2, that is ', i
        sem.release()
        gevent.sleep(0.3)


t1 = gevent.spawn(f1)
t2 = gevent.spawn(f2)
gevent.joinall([t1, t2])

運行結果如下:


image.png

由輸出可以發(fā)現,程序會同時判斷是否在sleep以及是否有鎖兩種情況出爹,然后執(zhí)行當前的最有操作庄吼。

小結

????gevent的優(yōu)勢不僅僅是在代碼中調用方便,厲害的是它擁有的monkey機制严就。假設你不愿意修改原來已經寫好的python代碼总寻,但是又想充分利用gevent機制,那么你就可以用monkey來做到這一點盈蛮。你所要做的就是在文件開頭打一個patch废菱,那么它就會自動替換你原來的thread、socket抖誉、time殊轴、multiprocessing等代碼,全部變成gevent框架袒炉。這一切都是由gevent自動完成的旁理。注意這個patch是在所有module都import了之后再打,否則沒有效果我磁。
????甚至在編寫的Web App代碼的時候孽文,不需要引入gevent的包,也不需要改任何代碼夺艰,僅僅在部署的時候芋哭,用一個支持gevent的WSGI服務器,就可以獲得數倍的性能提升郁副。

本文簡單介紹了gevent的使用减牺,下一篇將對gevent的部分源碼進行分析。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末存谎,一起剝皮案震驚了整個濱河市拔疚,隨后出現的幾起案子,更是在濱河造成了極大的恐慌既荚,老刑警劉巖稚失,帶你破解...
    沈念sama閱讀 221,888評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異恰聘,居然都是意外死亡句各,警方通過查閱死者的電腦和手機吸占,發(fā)現死者居然都...
    沈念sama閱讀 94,677評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來诫钓,“玉大人旬昭,你說我怎么就攤上這事【龋” “怎么了问拘?”我有些...
    開封第一講書人閱讀 168,386評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長惧所。 經常有香客問我骤坐,道長,這世上最難降的妖魔是什么下愈? 我笑而不...
    開封第一講書人閱讀 59,726評論 1 297
  • 正文 為了忘掉前任纽绍,我火速辦了婚禮,結果婚禮上势似,老公的妹妹穿的比我還像新娘拌夏。我一直安慰自己,他們只是感情好履因,可當我...
    茶點故事閱讀 68,729評論 6 397
  • 文/花漫 我一把揭開白布障簿。 她就那樣靜靜地躺著,像睡著了一般栅迄。 火紅的嫁衣襯著肌膚如雪站故。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,337評論 1 310
  • 那天毅舆,我揣著相機與錄音西篓,去河邊找鬼。 笑死憋活,一個胖子當著我的面吹牛岂津,可吹牛的內容都是我干的。 我是一名探鬼主播悦即,決...
    沈念sama閱讀 40,902評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼寸爆,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了盐欺?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,807評論 0 276
  • 序言:老撾萬榮一對情侶失蹤仅醇,失蹤者是張志新(化名)和其女友劉穎冗美,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體析二,經...
    沈念sama閱讀 46,349評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡粉洼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,439評論 3 340
  • 正文 我和宋清朗相戀三年节预,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片属韧。...
    茶點故事閱讀 40,567評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡安拟,死狀恐怖,靈堂內的尸體忽然破棺而出宵喂,到底是詐尸還是另有隱情糠赦,我是刑警寧澤,帶...
    沈念sama閱讀 36,242評論 5 350
  • 正文 年R本政府宣布锅棕,位于F島的核電站拙泽,受9級特大地震影響,放射性物質發(fā)生泄漏裸燎。R本人自食惡果不足惜顾瞻,卻給世界環(huán)境...
    茶點故事閱讀 41,933評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望德绿。 院中可真熱鬧荷荤,春花似錦、人聲如沸移稳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽秒裕。三九已至袱蚓,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間几蜻,已是汗流浹背喇潘。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留梭稚,地道東北人颖低。 一個月前我還...
    沈念sama閱讀 48,995評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像弧烤,于是被迫代替她去往敵國和親忱屑。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,585評論 2 359

推薦閱讀更多精彩內容