greenlet
為了更好使用協(xié)程來完成多任務(wù)昨凡,python中的greenlet模塊對其封裝,從而使得切換任務(wù)變的更加簡單
安裝方式
使用如下命令安裝greenlet模塊:
sudo pip3 install greenlet
#coding=utf-8fromgreenletimportgreenletimporttimedeftest1():whileTrue:print"---A--"gr2.switch()? ? ? ? time.sleep(0.5)deftest2():whileTrue:print"---B--"gr1.switch()? ? ? ? time.sleep(0.5)gr1 = greenlet(test1)gr2 = greenlet(test2)#切換到gr1中運行g(shù)r1.switch()
運行效果
---A--
---B--
---A--
---B--
---A--
---B--
---A--
---B--
...省略...
gevent
greenlet已經(jīng)實現(xiàn)了協(xié)程涝滴,但是這個還的人工切換,是不是覺得太麻煩了胶台,不要捉急歼疮,python還有一個比greenlet更強(qiáng)大的并且能夠自動切換任務(wù)的模塊gevent
其原理是當(dāng)一個greenlet遇到IO(指的是input output 輸入輸出,比如網(wǎng)絡(luò)诈唬、文件操作等)操作時韩脏,比如訪問網(wǎng)絡(luò),就自動切換到其他的greenlet铸磅,等到IO操作完成赡矢,再在適當(dāng)?shù)臅r候切換回來繼續(xù)執(zhí)行。
由于IO操作非常耗時阅仔,經(jīng)常使程序處于等待狀態(tài)吹散,有了gevent為我們自動切換協(xié)程,就保證總有g(shù)reenlet在運行八酒,而不是等待IO
安裝
pip3 install gevent
1. gevent的使用
importgeventdeff(n):foriinrange(n):? ? ? ? print(gevent.getcurrent(), i)g1 = gevent.spawn(f,5)g2 = gevent.spawn(f,5)g3 = gevent.spawn(f,5)g1.join()g2.join()g3.join()
運行結(jié)果
012340123401234
可以看到空民,3個greenlet是依次運行而不是交替運行
2. gevent切換執(zhí)行
importgeventdeff(n):foriinrange(n):? ? ? ? print(gevent.getcurrent(), i)#用來模擬一個耗時操作,注意不是time模塊中的sleepgevent.sleep(1)g1 = gevent.spawn(f,5)g2 = gevent.spawn(f,5)g3 = gevent.spawn(f,5)g1.join()g2.join()g3.join()
運行結(jié)果
000111222333444
3. 給程序打補(bǔ)丁
fromgeventimportmonkeyimportgeventimportrandomimporttimedefcoroutine_work(coroutine_name):foriinrange(10):? ? ? ? print(coroutine_name, i)? ? ? ? time.sleep(random.random())gevent.joinall([? ? ? ? gevent.spawn(coroutine_work,"work1"),? ? ? ? gevent.spawn(coroutine_work,"work2")])
運行結(jié)果
work10work11work12work13work14work15work16work17work18work19work20work21work22work23work24work25work26work27work28work29
fromgeventimportmonkeyimportgeventimportrandomimporttime# 有耗時操作時需要monkey.patch_all()# 將程序中用到的耗時操作的代碼羞迷,換為gevent中自己實現(xiàn)的模塊defcoroutine_work(coroutine_name):foriinrange(10):? ? ? ? print(coroutine_name, i)? ? ? ? time.sleep(random.random())gevent.joinall([? ? ? ? gevent.spawn(coroutine_work,"work1"),? ? ? ? gevent.spawn(coroutine_work,"work2")])
運行結(jié)果
work10work20work11work12work13work21work14work22work15work23work16work17work18work24work25work19work26work27work28work29