協程gevent模組和猴子補丁

2022-06-22 22:42:11 字數 3390 閱讀 1721

#

pip 裝模組 greenlet和gevent#協程

#與程序、執行緒一樣也是實現併發的手段

#建立乙個執行緒、關閉乙個執行緒都需要建立暫存器、棧等、需要消耗時間

#協程本質上是乙個執行緒

#能夠在多個任務之間切換來節省一些io時間

#協程中任務之間的切換時間開銷,要遠遠小於程序或執行緒之間的切換

#4cpu中,程序一般建立4+1個程序 + 乙個程序中線程為4*5 + 乙個執行緒中建立500個協程,一般這是一台4cpu的機器電腦上能達到好的效率的併發程度,50000個併發。nginx這種負載均衡的東西就是這種思路##

def cosumer():

#'''

#生成器函式:

#:return:

#'''

#while 1:

#x = yield

#print('處理消費了資料', x)##

#if __name__ == '__main__':

#c = cosumer() # 得到生成器

#next(c) # 走到生成器函式中的第乙個yield

#c.send(2) # 將2給了生成器函式中的x並執行print然後又到了yield那

## 在乙個函式中控制另外乙個函式,讓這兩個函式來回切換執行,下面用的是生成器實現的。協程效果

#def cosumer():

#'''

#生成器函式:

#:return:

#'''

#while 1:

#x = yield

#print('處理消費了資料', x)##

def producer():

#c = cosumer()

#next(c)

#for i in range(10):

#print('生產了資料', i)

#c.send(i)##

if __name__ == '__main__':

#producer()

#真正的協程實現任務之間的切換.

#真正的協程模組就是使用greenlet完成的任務之間的切換。省去了io時間,當乙個任務發生io時,肯定會阻塞,此時這個時候去切換任務讓另乙個任務工作,另乙個任務工作切換回來時,這個任務的io時間正好結束,這就是協程想達到的效果,節省io的切換時間

#import time

#from greenlet import greenlet##

def eat():

#print('eating start')

#g2.switch() # 切換到play中執行

#print('eating end')##

def play():

#print('playing start')

#g1.switch() #切換到eat中執行##

g1 = greenlet(eat) # eat任務放到greenlet中

#g2 = greenlet(play) # play任務放到greenlet中

#g1.switch() # 切換到eat任務執行到g2.switch()

## 列印資訊為

## eating start

## playing start

## eating end##

# process finished with exit code 0

#gevent模組

#import gevent##

def eat():

#print('eating start')

#gevent.sleep(1) # 發生io阻塞,切換到play

#print('eating end')##

def play():

#print('playing start')

#gevent.sleep(1) # 發生io阻塞,切換到eat##

g1 = gevent.spawn(eat)

#g2 = gevent.spawn(play)

#g1.join() # 因為是非同步的,如果不呼叫join,則直接執行到了下面,這樣主程序就會結束,這裡阻塞等待協程的結束

#g2.join()

#gevent模組

#協程,在乙個執行緒中來回的切換。這個切換過程不是作業系統做的,而是gevent做的

#在這個patch_all後面的所有模組中,發生的阻塞都會有gevent的效果

##from gevent import monkey;monkey.patch_all()

#import time

#import gevent##

def eat():

#print('eating start')

#time.sleep(1) # 發生io阻塞,切換到play.因為有了mokey.patch_all所以這裡等同於gevent.sleep(1),遇見io就會切換

#print('eating end')##

def play():

#print('playing start')

#time.sleep(1) # 發生io阻塞,切換到eat

#print('playing end')##

if __name__ == '__main__':

#g1 = gevent.spawn(eat)

#g2 = gevent.spawn(play)

#g1.join() # 阻塞等待協程執行結束

#g2.join() #

#協程任務之間的切換由程式**(gevent)完成,只有遇到協程模組能識別到的io操作的時候,程式才會進行協程切換,實現併發的效果

#同步和非同步(協程實現)

from gevent import monkey;monkey.patch_all() #

猴子補丁,必須放到最前面,這樣所有模組中的方法發生了io阻塞時,就會觸發協程的切換

import

time

import

gevent

deftask():

time.sleep(1)

print(12345)

defsync():

for i in range(2):

task()

defasync():

g_lst =

for i in range(10):

g = gevent.spawn(task) #

建立協程

gevent.joinall(g_lst)

#阻塞等待協程完畢

async()

#非同步的列印12345

協程:能夠在乙個執行緒中實現併發效果的概念,能夠巧妙的利用任務中的io阻塞時間,在任務的執行過程中,檢測到io操作時就能夠協程切換到別的任務中執行

協程 猴子補丁

from greenlet import greenlet import time def task1 temp print print 執行任務a str2 b.switch time.sleep 1 print 執行任務a完成 str str2 str temp def task2 print ...

python 協程 gevent模組

import requests 匯入 gevent import gevent 由於切換是在io操作時自動完成 所以gevent需要修改python自帶的一些標準庫 這一過程在啟動時通過monkey patch 猴子補丁 完成 from gevent import monkey monkey.pat...

python之gevent模組實現協程

python通過yield提供了對協程的基本支援,但是不完全。而第三方的gevent為python提供了比較完善的協程支援。gevent是第三方庫,通過greenlet實現協程,其基本思想是 當乙個greenlet遇到io操作時,比如訪問網路,就自動切換到其他的greenlet,等到io操作完成,再...