0.生成器
1.使用yield完成多任務
import timedef task_1():while True:print("---1----")time.sleep(0.1)yielddef task_2():while True:print("---2----")time.sleep(0.1)yielddef main():t1 = task_1()t2 = task_2()# 先讓t1運行一會,當t1中遇到yield的時候,再返回到24行,然后# 執行t2,當它遇到yield的時候,再次切換到t1中# 這樣t1/t2/t1/t2的交替運行,最終實現了多任務....協程while True:next(t1)next(t2)if __name__ == "__main__":main()
運行結果:
---1----
---2----
---1----
---2----
---1----
---2----
---1----
...
2.使用greenlet完成多任務
from greenlet import greenlet
import timedef test1():while True:print("---A--")gr2.switch()time.sleep(0.5)def test2():while True:print("---B--")gr1.switch()time.sleep(0.5)#創建生成器對象
gr1 = greenlet(test1)
gr2 = greenlet(test2)#切換到gr1中運行,開始輸出
gr1.switch()
運行結果:
---A--
---B--
---A--
---B--
---A--
....
3.使用gevent完成多任務
import gevent
import timedef f1(n):for i in range(n):print(gevent.getcurrent(), i)# time.sleep(0.5)gevent.sleep(0.5) #延時、堵塞等操作,都需要換成gevent里邊的相應方法def f2(n):for i in range(n):print(gevent.getcurrent(), i)# time.sleep(0.5)gevent.sleep(0.5) #延時、堵塞等操作,都需要換成gevent里邊的相應方法def f3(n):for i in range(n):print(gevent.getcurrent(), i)# time.sleep(0.5)gevent.sleep(0.5) #延時、堵塞等操作,都需要換成gevent里邊的相應方法print("----1---")
g1 = gevent.spawn(f1, 5)
print("----2---")
g2 = gevent.spawn(f2, 5)
print("----3---")
g3 = gevent.spawn(f3, 5)
print("----4---")
g1.join() # 堵塞,等待完成
g2.join() # 堵塞,等待完成
g3.join() # 堵塞,等待完成
運行結果:
----1---
----2---
----3---
----4---
<Greenlet at 0x15bf8f917b8: f1(5)> 0
<Greenlet at 0x15bf8f918c8: f2(5)> 0
<Greenlet at 0x15bf8f919d8: f3(5)> 0
<Greenlet at 0x15bf8f917b8: f1(5)> 1
<Greenlet at 0x15bf8f918c8: f2(5)> 1
<Greenlet at 0x15bf8f919d8: f3(5)> 1
<Greenlet at 0x15bf8f917b8: f1(5)> 2
<Greenlet at 0x15bf8f918c8: f2(5)> 2
<Greenlet at 0x15bf8f919d8: f3(5)> 2
<Greenlet at 0x15bf8f917b8: f1(5)> 3
<Greenlet at 0x15bf8f918c8: f2(5)> 3
<Greenlet at 0x15bf8f919d8: f3(5)> 3
<Greenlet at 0x15bf8f917b8: f1(5)> 4
<Greenlet at 0x15bf8f918c8: f2(5)> 4
<Greenlet at 0x15bf8f919d8: f3(5)> 4
注意,此時使用的延時是gevent.sleep(0.5),若使用time.sleep(0.5),則輸出結果如下:
----1---
----2---
----3---
----4---
<Greenlet at 0x2b3ce8917b8: f1(5)> 0
<Greenlet at 0x2b3ce8917b8: f1(5)> 1
<Greenlet at 0x2b3ce8917b8: f1(5)> 2
<Greenlet at 0x2b3ce8917b8: f1(5)> 3
<Greenlet at 0x2b3ce8917b8: f1(5)> 4
<Greenlet at 0x2b3ce8918c8: f2(5)> 0
<Greenlet at 0x2b3ce8918c8: f2(5)> 1
<Greenlet at 0x2b3ce8918c8: f2(5)> 2
<Greenlet at 0x2b3ce8918c8: f2(5)> 3
<Greenlet at 0x2b3ce8918c8: f2(5)> 4
<Greenlet at 0x2b3ce8919d8: f3(5)> 0
<Greenlet at 0x2b3ce8919d8: f3(5)> 1
<Greenlet at 0x2b3ce8919d8: f3(5)> 2
<Greenlet at 0x2b3ce8919d8: f3(5)> 3
<Greenlet at 0x2b3ce8919d8: f3(5)> 4
4.gevent打補丁
有耗時操作時,需要將程序中用到的耗時操作的代碼,替換成gevent中自己實現的模塊,比如講time.sleep(0.5)自動替換gevent.sleep(0.5),需要打補丁,方法如下:
首先導入:from gevent import monkey
然后執行:monkey.patch_all()
import gevent
import time
from gevent import monkey# 有耗時操作時,需要將程序中用到的耗時操作的代碼,替換成gevent中自己實現的模塊
monkey.patch_all()def f1(n):for i in range(n):print(gevent.getcurrent(), i)time.sleep(0.5)def f2(n):for i in range(n):print(gevent.getcurrent(), i)time.sleep(0.5)def f3(n):for i in range(n):print(gevent.getcurrent(), i)time.sleep(0.5)print("----1---")
g1 = gevent.spawn(f1, 5)
print("----2---")
g2 = gevent.spawn(f2, 5)
print("----3---")
g3 = gevent.spawn(f3, 5)
print("----4---")
g1.join()
g2.join()
g3.join()