日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

协程:Greenlet模块、Gevent模块

發布時間:2025/3/14 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 协程:Greenlet模块、Gevent模块 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

三、Greenlet模塊? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

Greenlet是python的一個C擴展,來源于Stackless python,旨在提供可自行調度的‘微線程’, 即協程。generator實現的協程在yield value時只能將value返回給調用者(caller)。 而在greenlet中,target.switch(value)可以切換到指定的協程(target), 然后yield value。greenlet用switch來表示協程的切換,從一個協程切換到另一個協程需要顯式指定。安裝 :pip3 install greenlet 簡介: from greenlet import greenletdef eat(name):print('%s eat 1' %name)g2.switch('egon')print('%s eat 2' %name)g2.switch() def play(name):print('%s play 1' %name)g1.switch()print('%s play 2' %name)g1=greenlet(eat) g2=greenlet(play)g1.switch('egon')#可以在第一次switch時傳入參數,以后都不需要 greenlet實現狀態切換

有幾個缺點
1.手動切換
2.不能規避I/O操作(睡眠)

?

gevent模塊?

安裝:pip3 install geventGevent 是一個第三方庫,可以輕松通過gevent實現并發同步或異步編程,在gevent中用到的主要模式是Greenlet, 它是以C擴展模塊形式接入Python的輕量級協程。 Greenlet全部運行在主程序操作系統進程的內部,但它們被協作式地調度。 介紹、安裝 g1=gevent.spawn(func,1,,2,3,x=4,y=5)創建一個協程對象g1,spawn括號內第一個參數是函數名,如eat,后面可以有多個參數,可以是位置實參或關鍵字實參,都是傳給函數eat的g2=gevent.spawn(func2)g1.join() #等待g1結束 g2.join() #等待g2結束#或者上述兩步合作一步:gevent.joinall([g1,g2]) g1.value#拿到func1的返回值#例:遇到io主動切換from gevent import monkey;monkey.patch_all()import gevent import time def eat():print('eat food 1')time.sleep(2)print('eat food 2')def play():print('play 1')time.sleep(1)print('play 2')g1=gevent.spawn(eat) g2=gevent.spawn(play) gevent.joinall([g1,g2]) print('') 用法介紹 真正能實現協程的模塊geventimport gevent def eat():print('eating1')print('eating2') g1 = gevent.spawn(eat) #創建一個協程對象g1 #執行輸出為空,表示它還沒執行。import gevent def eat():print('eating1')print('eating2') g1 = gevent.spawn(eat) #創建一個協程對象g1 g1.join() #等待g1結束#執行輸出:#eating1 #eating2 例子

geven 不能識別time.sleep()? 需要用gevent.sleep()? 或者導入一個模塊monkey;monkey patch (猴子補丁)

#如果想讓協程執行time.sleep()呢?由于默認,協程無法識別time.sleep()方法,需要導入一個模塊monkey#monkey patch (猴子補丁) #用來在運行時動態修改已有的代碼,而不需要修改原始代碼。from gevent import monkey;monkey.patch_all() # 它會把下面導入的所有的模塊中的IO操作都打成一個包,gevent就能夠認識這些IO了 import time import gevent def eat():print('eating1')time.sleep(1) #延時調用print('eating2')def play():print('playing1')time.sleep(1) #延時調用print('playing2')g1 = gevent.spawn(eat) #創建一個協程對象g1 g2 = gevent.spawn(play) g1.join() #等待g1結束 g2.join()#執行輸出: eating1 playing1 eating2 playing2 使用

結論:

使用gevent模塊來執行多個函數,表示在這些函數遇到IO操作的時候可以在同一個線程中進行切換
利用其他任務的IO阻塞時間來切換到其他的任務繼續執行

前提是:

spawn來發布協程任務
join負責開啟并等待任務執行結束
gevent本身不認識其他模塊中的IO操作,但是如果我們在導入其他模塊之前執行from gevent import monkey;monkey.patch_all()? 這行代碼,必須在文件最開頭
gevent就能夠認識在這句話之后導入的模塊中的所有IO操作了

Gevent之同步與異步

from gevent import spawn,joinall,monkey;monkey.patch_all()import time def task(pid):"""Some non-deterministic task"""time.sleep(0.5)print('Task %s done' % pid)def synchronous(): # 同步for i in range(10):task(i)def asynchronous(): # 異步g_l=[spawn(task,i) for i in range(10)]joinall(g_l)print('DONE')if __name__ == '__main__':print('Synchronous:')synchronous()print('Asynchronous:')asynchronous() # 上面程序的重要部分是將task函數封裝到Greenlet內部線程的gevent.spawn。 # 初始化的greenlet列表存放在數組threads中,此數組被傳給gevent.joinall 函數, # 后者阻塞當前流程,并執行所有給定的greenlet任務。執行流程只會在 所有greenlet執行完后才會繼續向下走。 實例

當一個任務執行時,依賴另外一個任務的結果時,這種情況不適合異步,只能用同步

Gevent之應用舉例一

Gevent之應用舉例二

轉載于:https://www.cnblogs.com/python-by-xiaoma/p/10300000.html

總結

以上是生活随笔為你收集整理的协程:Greenlet模块、Gevent模块的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。