日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

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

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

立即學(xué)習(xí):https://edu.csdn.net/course/play/24458/296457?utm_source=blogtoedu

協(xié)程(yield,greenlet,gevent)

?

1.協(xié)程:在單線程中通過(guò)不斷地在多個(gè)任務(wù)之間進(jìn)行切換執(zhí)行,來(lái)達(dá)到并發(fā)的效果的線程,可以提高效率

?

2.yield實(shí)現(xiàn)協(xié)程

#yield = return + generator(生成器) #有yield的函數(shù)就是生成器,不會(huì)直接執(zhí)行函數(shù),首先獲得生成器對(duì)象然后使用next函數(shù)這才開(kāi)始運(yùn)行函數(shù) #next方法#并發(fā)執(zhí)行 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實(shí)現(xiàn)協(xié)程

#greenlet也是i一個(gè)可以實(shí)現(xiàn)單線程內(nèi)并發(fā)的效果,但是和yield一樣不能檢測(cè)i/o模型 #切換的格式為: ''' g1 = greenlet(function1)#獲得對(duì)象 g2.switch(para)#從當(dāng)前任務(wù)切換到g2對(duì)應(yīng)的任務(wù)中 ''' #協(xié)程并發(fā) from greenlet import greenlet#定義函數(shù)一 def eat(name):print('%s1 is eating'%name)g2.switch('同學(xué)')print('%s2 is eating'%name)g2.switch()#定義函數(shù)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('同學(xué)')

?

4.gevent實(shí)現(xiàn)協(xié)程

#1.gevent模塊是基于greenlet模塊的,具有檢測(cè)自身I/O操作的功能 import gevent,time#定義任務(wù)1 def eat(name):print('%s eat 1'%name)#自身的I/O操作。可以被檢測(cè)出,一旦檢測(cè)出就自動(dòng)進(jìn)行任務(wù)·切換gevent.sleep(3)print('%s eat 2'%name)#定義任務(wù)2 def play(name):print('%s play 1'%name)gevent.sleep(4)print('%s play 2'%name)start_time = time.time() #創(chuàng)建gevent對(duì)象,只是提交了任務(wù),要想出結(jié)果,必須跟join函數(shù)配對(duì)使用 g1 = gevent.spawn(eat,'john') g2 = gevent.spawn(play,'lucy')g1.join() g2.join() end_time = time.time() print(end_time-start_time) ''' 運(yùn)行結(jié)果: john eat 1 lucy play 1 john eat 2 lucy play 2 4.0197389125823975#運(yùn)行時(shí)間接近4秒,即兩個(gè)任務(wù)并發(fā)執(zhí)行的#首先該程序是單線程,只有一個(gè)主線程,但是含有兩個(gè)任務(wù),首先按照代碼從上到下執(zhí)行, 執(zhí)行到創(chuàng)建對(duì)象時(shí),會(huì)自動(dòng)跳轉(zhuǎn)到對(duì)應(yīng)的函數(shù)中去,如g1跳到eat函數(shù),執(zhí)行第一次打印, 檢測(cè)到自身gevent.sleep()I/O操作后,就自動(dòng)切換到下一個(gè)任務(wù),執(zhí)行play函數(shù)的第一次 打印,后面就是兩個(gè)任務(wù)均處于等待狀態(tài),期間一直在兩個(gè)任務(wù)之間切換進(jìn)行檢測(cè),因?yàn)閑at時(shí)間短, 所以先執(zhí)行eat函數(shù)的第二次打印任務(wù),接著就是Play的第二次打印#因此這里實(shí)現(xiàn)了單線程兩個(gè)任務(wù)并發(fā)的效果 '''#2.gevent模塊是基于greenlet模塊的,具有檢測(cè)自身I/O操作的功能,不能檢測(cè)自身以外的I/O操作,如time.sleep() import gevent,time#定義任務(wù)1 def eat(name):print('%s eat 1'%name)#自身的I/O操作。可以被檢測(cè)出,一旦檢測(cè)出就自動(dòng)進(jìn)行任務(wù)·切換time.sleep(3)print('%s eat 2'%name)#定義任務(wù)2 def play(name):print('%s play 1'%name)time.sleep(4)print('%s play 2'%name)start_time = time.time() #創(chuàng)建gevent對(duì)象,只是異步提交了任務(wù),不會(huì)等結(jié)果的出來(lái),要想出結(jié)果,必須跟join函數(shù)或者和joinall()配對(duì)使用, 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 #運(yùn)行時(shí)間接近與兩個(gè)任務(wù)I/O操作的時(shí)間總和,因此gevent不能檢測(cè)出自身以為的I/O操作 '''#3.gevent.monkey.patch_all():可以檢測(cè)到自身以外的I/O操作 import gevent,time from gevent import monkey monkey.patch_all()#定義任務(wù)1 def eat(name):print('%s eat 1'%name)#自身的I/O操作。可以被檢測(cè)出,一旦檢測(cè)出就自動(dòng)進(jìn)行任務(wù)·切換time.sleep(3)print('%s eat 2'%name)#定義任務(wù)2 def play(name):print('%s play 1'%name)time.sleep(4)print('%s play 2'%name)start_time = time.time() #創(chuàng)建gevent對(duì)象,只是提交了任務(wù),要想出結(jié)果,必須跟join函數(shù)配對(duì)使用 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#說(shuō)明檢測(cè)到了time.sleep()的I/O操作,自動(dòng)進(jìn)行切換,實(shí)現(xiàn)了單線程并發(fā)的效果 '''

?

總結(jié)

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

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。