Python-greenlet完成多任务(代替yield),使用gevent完成多任务(协程)

Posted JerryZao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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  )

 

 

 

 

 

 

 

 

 

以上是关于Python-greenlet完成多任务(代替yield),使用gevent完成多任务(协程)的主要内容,如果未能解决你的问题,请参考以下文章

python-greenlet模块(协程)

使用AtomicInteger原子类代替i++线程安全操作

并发编程之美

进程线程对比

python之多线程

线程vs进程,多线程实例