Python-greenlet完成多任务(代替yield),使用gevent完成多任务(协程)
gevent 实现多任务:
import gevent # 遇到延时就切换任务 def f1(n): for i in range(n): print(gevent.getcurrent(), i) gevent.sleep(0.5) # 必须用自己的延时,不能用time模块的延时 def f2(n): for i in range(n): print(gevent.getcurrent(), i) gevent.sleep(0.5) def f3(n): for i in range(n): print(gevent.getcurrent(), i) gevent.sleep(0.5) g1 = gevent.spawn(f1, 5) # grenlet 对象 g2 = gevent.spawn(f2, 5) g3 = gevent.spawn(f3, 5) g1.join() # 堵塞,+ 延时,切换 g2.join() g3.join()
结果:
1 D:\python3.7\python.exe E:/code_pycharm/test_in_class/tt13.py 2 <Greenlet "Greenlet-0" at 0x29a36a8: f1(5)> 0 3 <Greenlet "Greenlet-1" at 0x29a37b8: f2(5)> 0 4 <Greenlet "Greenlet-2" at 0x29a38c8: f3(5)> 0 5 <Greenlet "Greenlet-0" at 0x29a36a8: f1(5)> 1 6 <Greenlet "Greenlet-1" at 0x29a37b8: f2(5)> 1 7 <Greenlet "Greenlet-2" at 0x29a38c8: f3(5)> 1 8 <Greenlet "Greenlet-0" at 0x29a36a8: f1(5)> 2 9 <Greenlet "Greenlet-1" at 0x29a37b8: f2(5)> 2 10 <Greenlet "Greenlet-2" at 0x29a38c8: f3(5)> 2 11 <Greenlet "Greenlet-0" at 0x29a36a8: f1(5)> 3 12 <Greenlet "Greenlet-1" at 0x29a37b8: f2(5)> 3 13 <Greenlet "Greenlet-2" at 0x29a38c8: f3(5)> 3 14 <Greenlet "Greenlet-0" at 0x29a36a8: f1(5)> 4 15 <Greenlet "Greenlet-1" at 0x29a37b8: f2(5)> 4 16 <Greenlet "Greenlet-2" at 0x29a38c8: f3(5)> 4 17 18 Process finished with exit code 0
使用猴子补丁,可以不用把所有耗时的,阻塞的用gevent里的代替,该怎么写就怎么写。
如:time.sleep()的使用
1 import gevent 2 import time 3 from gevent import monkey 4 5 monkey.patch_all() 6 7 # 遇到延时就切换任务 8 def f1(n): 9 for i in range(n): 10 print(gevent.getcurrent(), i) 11 # gevent.sleep(0.5) # 必须用自己的延时,不能用time模块的延时 12 time.sleep(0.5) 13 14 def f2(n): 15 for i in range(n): 16 print(gevent.getcurrent(), i) 17 gevent.sleep(0.5) 18 19 def f3(n): 20 for i in range(n): 21 print(gevent.getcurrent(), i) 22 gevent.sleep(0.5) 23 24 g1 = gevent.spawn(f1, 5) # grenlet 对象 25 g2 = gevent.spawn(f2, 5) 26 g3 = gevent.spawn(f3, 5) 27 g1.join() # 堵塞,+ 延时,切换 28 g2.join() 29 g3.join()
结果:
1 D:\python3.7\python.exe E:/code_pycharm/test_in_class/tt13.py 2 <Greenlet "Greenlet-0" at 0x3603268: f1(5)> 0 3 <Greenlet "Greenlet-1" at 0x3603598: f2(5)> 0 4 <Greenlet "Greenlet-2" at 0x3603488: f3(5)> 0 5 <Greenlet "Greenlet-0" at 0x3603268: f1(5)> 1 6 <Greenlet "Greenlet-1" at 0x3603598: f2(5)> 1 7 <Greenlet "Greenlet-2" at 0x3603488: f3(5)> 1 8 <Greenlet "Greenlet-0" at 0x3603268: f1(5)> 2 9 <Greenlet "Greenlet-1" at 0x3603598: f2(5)> 2 10 <Greenlet "Greenlet-2" at 0x3603488: f3(5)> 2 11 <Greenlet "Greenlet-0" at 0x3603268: f1(5)> 3 12 <Greenlet "Greenlet-1" at 0x3603598: f2(5)> 3 13 <Greenlet "Greenlet-2" at 0x3603488: f3(5)> 3 14 <Greenlet "Greenlet-0" at 0x3603268: f1(5)> 4 15 <Greenlet "Greenlet-1" at 0x3603598: f2(5)> 4 16 <Greenlet "Greenlet-2" at 0x3603488: f3(5)> 4 17 18 Process finished with exit code 0
用gevet.joinall
1 import gevent 2 import time 3 from gevent import monkey 4 5 monkey.patch_all() 6 7 # 遇到延时就切换任务 8 def f1(n): 9 for i in range(n): 10 print(gevent.getcurrent(), i) 11 # gevent.sleep(0.5) # 必须用自己的延时,不能用time模块的延时 12 time.sleep(0.5) 13 14 def f2(n): 15 for i in range(n): 16 print(gevent.getcurrent(), i) 17 gevent.sleep(0.5) 18 19 def f3(n): 20 for i in range(n): 21 print(gevent.getcurrent(), i) 22 gevent.sleep(0.5) 23 24 gevent.joinall( 25 gevent.spawn(f1, 5), 26 gevent.spawn(f2, 5), 27 gevent.spawn(f3, 5) 28 29 )
为什么要坚持,想一想当初!