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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

学习笔记(35):Python网络编程并发编程-协程(yield,greenlet,gevent模块)

發布時間:2023/12/10 python 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 学习笔记(35):Python网络编程并发编程-协程(yield,greenlet,gevent模块) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

立即學習:https://edu.csdn.net/course/play/24458/296457?utm_source=blogtoedu

協程(yield,greenlet,gevent)

?

1.協程:在單線程中通過不斷地在多個任務之間進行切換執行,來達到并發的效果的線程,可以提高效率

?

2.yield實現協程

#yield = return + generator(生成器) #有yield的函數就是生成器,不會直接執行函數,首先獲得生成器對象然后使用next函數這才開始運行函數 #next方法#并發執行 import time def productor():g = costumor()for i in range(100):res = next(g)print(res)def costumor():for i in range(100):res = yield "*"*5+"%s"%i+'*'*5if __name__ == '__main__':start_time = time.time()productor()end_time = time.time()print('%.9f'%float(end_time-start_time))#串行 def productor():res = costumor()for i in res:print('*'*5+str(i)+"*"*5)def costumor():res=[]for i in range(100):res.append(i)return resif __name__ == '__main__':start_time = time.time()productor()end_time = time.time()print('%.9f'%float(end_time-start_time))

?

3.greenlet實現協程

#greenlet也是i一個可以實現單線程內并發的效果,但是和yield一樣不能檢測i/o模型 #切換的格式為: ''' g1 = greenlet(function1)#獲得對象 g2.switch(para)#從當前任務切換到g2對應的任務中 ''' #協程并發 from greenlet import greenlet#定義函數一 def eat(name):print('%s1 is eating'%name)g2.switch('同學')print('%s2 is eating'%name)g2.switch()#定義函數2 def play(name):print('%s1 is playing'%name)g1.switch()print('%s2 is playing'%name)if __name__ == '__main__':g1 = greenlet(eat)g2 = greenlet(play)g1.switch('同學')

?

4.gevent實現協程

#1.gevent模塊是基于greenlet模塊的,具有檢測自身I/O操作的功能 import gevent,time#定義任務1 def eat(name):print('%s eat 1'%name)#自身的I/O操作。可以被檢測出,一旦檢測出就自動進行任務·切換gevent.sleep(3)print('%s eat 2'%name)#定義任務2 def play(name):print('%s play 1'%name)gevent.sleep(4)print('%s play 2'%name)start_time = time.time() #創建gevent對象,只是提交了任務,要想出結果,必須跟join函數配對使用 g1 = gevent.spawn(eat,'john') g2 = gevent.spawn(play,'lucy')g1.join() g2.join() end_time = time.time() print(end_time-start_time) ''' 運行結果: john eat 1 lucy play 1 john eat 2 lucy play 2 4.0197389125823975#運行時間接近4秒,即兩個任務并發執行的#首先該程序是單線程,只有一個主線程,但是含有兩個任務,首先按照代碼從上到下執行, 執行到創建對象時,會自動跳轉到對應的函數中去,如g1跳到eat函數,執行第一次打印, 檢測到自身gevent.sleep()I/O操作后,就自動切換到下一個任務,執行play函數的第一次 打印,后面就是兩個任務均處于等待狀態,期間一直在兩個任務之間切換進行檢測,因為eat時間短, 所以先執行eat函數的第二次打印任務,接著就是Play的第二次打印#因此這里實現了單線程兩個任務并發的效果 '''#2.gevent模塊是基于greenlet模塊的,具有檢測自身I/O操作的功能,不能檢測自身以外的I/O操作,如time.sleep() import gevent,time#定義任務1 def eat(name):print('%s eat 1'%name)#自身的I/O操作。可以被檢測出,一旦檢測出就自動進行任務·切換time.sleep(3)print('%s eat 2'%name)#定義任務2 def play(name):print('%s play 1'%name)time.sleep(4)print('%s play 2'%name)start_time = time.time() #創建gevent對象,只是異步提交了任務,不會等結果的出來,要想出結果,必須跟join函數或者和joinall()配對使用, g1 = gevent.spawn(eat,'john') g2 = gevent.spawn(play,'lucy')g1.join() g2.join() #gevent.joinall([g1,g2]) end_time = time.time() print(end_time-start_time) ''' john eat 1 john eat 2 lucy play 1 lucy play 2 7.019653797149658 #運行時間接近與兩個任務I/O操作的時間總和,因此gevent不能檢測出自身以為的I/O操作 '''#3.gevent.monkey.patch_all():可以檢測到自身以外的I/O操作 import gevent,time from gevent import monkey monkey.patch_all()#定義任務1 def eat(name):print('%s eat 1'%name)#自身的I/O操作。可以被檢測出,一旦檢測出就自動進行任務·切換time.sleep(3)print('%s eat 2'%name)#定義任務2 def play(name):print('%s play 1'%name)time.sleep(4)print('%s play 2'%name)start_time = time.time() #創建gevent對象,只是提交了任務,要想出結果,必須跟join函數配對使用 g1 = gevent.spawn(eat,'john') g2 = gevent.spawn(play,'lucy')g1.join() g2.join() end_time = time.time() print(end_time-start_time) ''' john eat 1 lucy play 1 john eat 2 lucy play 2 4.009758949279785#說明檢測到了time.sleep()的I/O操作,自動進行切換,實現了單線程并發的效果 '''

?

總結

以上是生活随笔為你收集整理的学习笔记(35):Python网络编程并发编程-协程(yield,greenlet,gevent模块)的全部內容,希望文章能夠幫你解決所遇到的問題。

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