python中的协程:greenlet和gevent
生活随笔
收集整理的這篇文章主要介紹了
python中的协程:greenlet和gevent
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
- 協(xié)程是一中多任務(wù)實(shí)現(xiàn)方式,它不需要多個(gè)進(jìn)程或線程就可以實(shí)現(xiàn)多任務(wù)。
1.通過yield實(shí)現(xiàn)協(xié)程:
代碼:
import time def A():while 1:print('------A-----')time.sleep(0.1)yield()def B():while 1:print('-------B-----')time.sleep(0.1)next(a)a = A()#全局變量 B()
執(zhí)行結(jié)果:
-------B-----
------A-----
-------B-----
------A-----
-------B-----
------A-----
-------B-----
------A-----
-------B-----
------A-----
?
?
2.greenlet:
- yield能實(shí)現(xiàn)協(xié)程,不過實(shí)現(xiàn)過程不易于理解,greenlet是在這方面做了改進(jìn)。
上代碼:
from greenlet import greenlet import timedef A():while 1:print('-------A-------')time.sleep(0.5)g2.switch()def B():while 1:print('-------B-------')time.sleep(0.5)g1.switch()g1 = greenlet(A) #創(chuàng)建協(xié)程g1 g2 = greenlet(B)g1.switch() #跳轉(zhuǎn)至協(xié)程g1上面代碼的原理是讓函數(shù)A和函數(shù)B,誰也別等誰,各自運(yùn)行,誰有輸出就算誰的.
執(zhí)行結(jié)果:
-------A------- -------B------- -------A------- -------B------- -------A------- ···3.gevent:
- greenlet可以實(shí)現(xiàn)協(xié)程,不過每一次都要人為的去指向下一個(gè)該執(zhí)行的協(xié)程,顯得太過麻煩。python還有一個(gè)比greenlet更強(qiáng)大的并且能夠自動(dòng)切換任務(wù)的模塊gevent
- gevent每次遇到io操作,需要耗時(shí)等待時(shí),會(huì)自動(dòng)跳到下一個(gè)協(xié)程繼續(xù)執(zhí)行。
上代碼:
import geventdef A():while 1:print('-------A-------')gevent.sleep(1) #用來模擬一個(gè)耗時(shí)操作,注意不是time模塊中的sleepdef B():while 1:print('-------B-------')gevent.sleep(0.5) #每當(dāng)碰到耗時(shí)操作,會(huì)自動(dòng)跳轉(zhuǎn)至其他協(xié)程g1 = gevent.spawn(A) # 創(chuàng)建一個(gè)協(xié)程 g2 = gevent.spawn(B) g1.join() #等待協(xié)程執(zhí)行結(jié)束 g2.join()執(zhí)行結(jié)果:
-------A------- -------B------- -------B------- -------A------- -------B------- -------B------- -------A------- -------B------- -------B------- ···4.協(xié)程gevent完成回顯服務(wù)器:
import gevent from gevent import monkey,socketmonkey.patch_all() #有IO才做時(shí)需要這一句s = socket.socket(2,1) #用的都是gevent模塊中的socket,但用法一樣 s.setsockopt(1,2,1) s.bind(('',8080)) s.listen(1024)def func_accept():while 1:cs,userinfo = s.accept()print('來了一個(gè)客戶'+str(userinfo))g = gevent.spawn(func_recv,cs) #每當(dāng)有用戶連接,增加一條協(xié)程def func_recv(cs):while 1:recv_data = cs.recv(1024)print(recv_data) #程誰堵塞了,便會(huì)跳轉(zhuǎn)至其他協(xié)程if len(recv_data) > 0:cs.send(recv_data)else:cs.close()breakg1 = gevent.spawn(func_accept) g1.join()?
- gevent的代碼風(fēng)格和線程非常相似,運(yùn)行出來后的效果也非常相似。
總結(jié)
以上是生活随笔為你收集整理的python中的协程:greenlet和gevent的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用gitkraken来push的流程
- 下一篇: 用eval在txt中存储list,dic